springBoot+gradle集成shiro实现登陆

本代码仅后台,前台代码使用前后台分离自己配置

一、引入shiro包

implementation("org.apache.shiro:shiro-core:$ShiroVersion",
		"org.apache.shiro:shiro-ehcache:$ShiroVersion",
		"org.apache.shiro:shiro-web:$ShiroVersion",
		"org.apache.shiro:shiro-quartz:$ShiroVersion",
		"org.apache.shiro:shiro-spring:1.3.2")

quartz引入之后必须配置,否则报错,暂时不用可在application注解上将其去掉

@SpringBootApplication(exclude = QuartzAutoConfiguration.class)

二、shiro配置ShiroConfig.java

import com.trgis.firstproject.framework.shiro.MyShiroRealm;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author ZHAO
 * @date 2019/1/8 17:49
 */
@Configuration
public class ShiroConfig {

    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login.html");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/index.html");
        // 未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        //自定义拦截器
        Map<String, Filter> filters = new LinkedHashMap<String, Filter>();
        //限制同一帐号同时在线的个数。
        //filtersMap.put("kickout", kickoutSessionControlFilter());
        shiroFilterFactoryBean.setFilters(filters);

        // 权限控制map.
        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/login", "anon");
        filterMap.put("/index", "anon");
        filterMap.put("/static/**", "anon");
        filterMap.put("/templates/**", "authc");
        // filterMap.put("/webjars/**", "anon");
        filterMap.put("/druid/**", "anon");
        filterMap.put("/api/**", "anon");
        filterMap.put("/**/*.css", "anon");
        filterMap.put("/**/*.js", "anon");
        filterMap.put("/**/*.html", "anon");
        filterMap.put("/images/**", "anon");
        filterMap.put("/fonts/**", "anon");
        // filterMap.put("/swagger/**", "anon");
        // filterMap.put("/favicon.ico", "anon");
        // filterMap.put("/", "anon");
        shiroFilterFactoryBean
                .setFilterChainDefinitionMap(filterMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public SessionManager sessionManager(){
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setSessionValidationSchedulerEnabled(true);
        sessionManager.setSessionIdCookieEnabled(false);
        sessionManager.setGlobalSessionTimeout(2*3600000);
        return sessionManager;
    }
    @Bean
    public SecurityManager securityManager(SessionManager sessionManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        securityManager.setSessionManager(sessionManager);
        return securityManager;
    }

    @Bean
    public MyShiroRealm myShiroRealm(){
        return new MyShiroRealm();
    }

    /**
     * cookie对象;
     * @return
     */
    public SimpleCookie rememberMeCookie(){
        //这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        //<!-- 记住我cookie生效时间30天 ,单位秒;-->
        simpleCookie.setMaxAge(2592000);
        return simpleCookie;
    }

    /**
     * cookie管理对象;记住我功能
     * @return
     */
    public CookieRememberMeManager rememberMeManager(){
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        //rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
        cookieRememberMeManager.setCipherKey(Base64.decode("3AvVhmFLUs0KTA3Kprsdag=="));
        return cookieRememberMeManager;
    }
}

三、自定义realm  MyShiroRealm.java

import com.trgis.firstproject.modules.sys.entity.User;
import com.trgis.firstproject.modules.sys.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

/**
 * @author ZHAO
 * @date 2019/1/8 18:22
 */
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    /**
     * 授权用户权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //获取用户角色
        Set<String> roleSet = new HashSet<>();
        roleSet.add("100002");
        info.setRoles(roleSet);

        //获取用户权限
        Set<String> permissionSet = new HashSet<>();
        permissionSet.add("权限添加");
        permissionSet.add("权限删除");
        info.setStringPermissions(permissionSet);

        return info;
    }

    /**
     * 验证用户身份
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        String username = token.getUsername();
        String password = String.valueOf(token.getPassword());
        User user = userService.findByAccount(username);
        // 抛出异常,在登陆处LoginController处处理(subject.login()接收异常)
        if(user.getDelFlag() == 1){
            throw new UnknownAccountException("验证未通过,用户无效!");
        }
        if(user == null || !user.getPassword().equals(password)) {
            throw new UnknownAccountException("验证 未通过,用户名密码错误!");
        }
        User userInfo = new User();
        userInfo.setAccount(user.getAccount());
        userInfo.setPassword(user.getPassword());
        user.setDelFlag(user.getDelFlag());
        setSession("user",userInfo);
        return new SimpleAuthenticationInfo(user, password, getName());
    }

    /**
     * 将一些数据放到ShiroSession中,以便于其它地方使用,将用户存放到session中
     * @see  // 比如Controller,使用时直接用HttpSession.getAttribute(key)就可以取到
     */
    private void setSession(Object key, Object value){
        Subject currentUser = SecurityUtils.getSubject();
        if(currentUser != null){
            Session session = currentUser.getSession();
            System.out.println(session.getId());
            if(null != session){
                // 2小时
                session.setTimeout(7200000);
                session.setAttribute(key, value);
            }
        }
    }
}

四、登陆控制层LoginController.java

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * 登陆控制层
 * @author ZHANG
 * @date 2019/01/08
 */
@Controller
public class LoginController {

    @RequestMapping(value = "/login", method={RequestMethod.POST, RequestMethod.GET})
    public void userLogin(@RequestParam("account") String username, @RequestParam("password") String password) {
        String userAccount = username;
        String userPassword = password;
        System.out.println(111 + userAccount + userPassword);
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        token.setRememberMe(true);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            System.out.println("账户错误");
        }

    }

}

五、实体类User.java

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

/**
 * 系统用户实体类
 * @author ZHANG
 * @date 2019/01/08
 */
@Entity
@Table(name = "users")
public class User implements Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @GenericGenerator(name = "generator", strategy = "native")
    @Column(name = "userid", unique = true, nullable = false)
    private Long userid;

    /**
     * 用户账号名
     */
    @Column(unique=true)
    private String account;

    /**
     * 密码默认值为123456
     */
    @Column
    private String password = "123456";

    /**
     * 用户名称
     */
    @Column
    private String name;

    /**
     * 用户性别
     */
    @Column
    private String gender;

    /**
     * 用户电子邮件
     */
    @Column
    private String email;

    /**
     * 用户电话号码
     */
    @Column
    private String telephone;

    /**
     * @是否是内部用户 0.是  1否
     */
    @Column
    private Integer isInner = 0;

    /**
     * 创建时间
     */
    @Column
    private Date creatTime;

    /**
     * 登录时间
     */
    private Date loginTime;

    /**
     * 上次登录时间
     */
    private Date lastLoginTime;

    /**
     * 最后登录失败时间
     */
    private Date lastLoginErrorTime;

    /**
     * 登录错误次数
     */
    private Integer loginErrorCount = 0;

    /**
     * 是否锁定(0,未锁定,1、锁定)
     */
    private Integer isLocked = 0;

    /**
     * 管理员是否更改过密码(0,未更改,1、更改)
     */
    private Integer isUpdatePassword;

    /**
     * 删除标志
     */
    @Column
    private Integer delFlag = 1;

    public Long getUserid() {
        return userid;
    }

    public void setUserid(Long userid) {
        this.userid = userid;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public Integer getIsInner() {
        return isInner;
    }

    public void setIsInner(Integer isInner) {
        this.isInner = isInner;
    }

    public Date getCreatTime() {
        return creatTime;
    }

    public void setCreatTime(Date creatTime) {
        this.creatTime = creatTime;
    }

    public Date getLoginTime() {
        return loginTime;
    }

    public void setLoginTime(Date loginTime) {
        this.loginTime = loginTime;
    }

    public Date getLastLoginTime() {
        return lastLoginTime;
    }

    public void setLastLoginTime(Date lastLoginTime) {
        this.lastLoginTime = lastLoginTime;
    }

    public Date getLastLoginErrorTime() {
        return lastLoginErrorTime;
    }

    public void setLastLoginErrorTime(Date lastLoginErrorTime) {
        this.lastLoginErrorTime = lastLoginErrorTime;
    }

    public Integer getLoginErrorCount() {
        return loginErrorCount;
    }

    public void setLoginErrorCount(Integer loginErrorCount) {
        this.loginErrorCount = loginErrorCount;
    }

    public Integer getIsLocked() {
        return isLocked;
    }

    public void setIsLocked(Integer isLocked) {
        this.isLocked = isLocked;
    }

    public Integer getIsUpdatePassword() {
        return isUpdatePassword;
    }

    public void setIsUpdatePassword(Integer isUpdatePassword) {
        this.isUpdatePassword = isUpdatePassword;
    }

    public Integer getDelFlag() {
        return delFlag;
    }

    public void setDelFlag(Integer delFlag) {
        this.delFlag = delFlag;
    }
}

最后写根据username查找用户方法即可     Dao层

import com.trgis.firstproject.modules.sys.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

/**
 * @author ZHAO
 * @date 2019/1/11 18:17
 */
@Repository
public interface UserDao extends JpaRepository<User, Long>,JpaSpecificationExecutor<User> {

    @Query(value="SELECT * from users where account = ?1", nativeQuery = true)
    User findByAccount(String username);
}

猜你喜欢

转载自blog.csdn.net/weixin_41996632/article/details/86469535
今日推荐