springboot-shiro用户登录鉴权

1、maven依赖

根据基础依赖spring-boot-starter-web找到对应的最新版本shiro依赖

        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.apache.shiro
            shiro-spring-boot-web-starter
            1.8.0
        

2、自定义relm

      继承AuthorizingRealm,自定义实现登录认证和授权两个方法

@Component("authorizer")
public class CustomRealm extends AuthorizingRealm {


    @Autowired
    SysUserService sysUserService;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录用户名
        String name = (String) principalCollection.getPrimaryPrincipal();
        //此处为数据库查询用户权限数据
        Set permissionSet = sysUserService.getPermissionsByName(name);

        //添加权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addStringPermissions(permissionSet);

        return simpleAuthorizationInfo;
    }

    //登录认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        Object principal =  authenticationToken.getPrincipal();
        Object credentials = authenticationToken.getCredentials();
        if (principal == null || credentials == null) {
            return null;
        }
        String name = String.valueOf(principal);
        //此处为数据库查询用户数据
        SysUser user = sysUserService.getUserByName(name);
        if (user == null) {
            return null;
        } else {
            return new SimpleAuthenticationInfo(name, user.getPassWord(), getName());
        }
    }
}

3、自定义ShiroFilterFactoryBean

        区分哪些路径需要鉴权,哪些路径不需要鉴权。

        默认在未登录情况下访问需要鉴权的路径会被自动重定向到login.jsp。前后端分离项目需要自定义到一个路径以返回json格式数据给前端。

@Configuration
public class ShiroConfig {


    @Autowired
    CustomRealm customRealm;

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(customRealm);
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        //重新定义login.jsp
        shiroFilterFactoryBean.setLoginUrl("/redirectToLogin");

        HashMap hashMap = new HashMap<>();
        //anon意为不需要鉴权,可以匿名访问的路径
        hashMap.put("/user/login", "anon");
        hashMap.put("/redirectToLogin", "anon");
        hashMap.put("/swagger-ui.html", "anon");
        hashMap.put("/swagger-resources/**", "anon");
        hashMap.put("/v2/**", "anon");

        //此句代表其他的都需要鉴权
        hashMap.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(hashMap);


        return shiroFilterFactoryBean;
    }


}

4、重定向login.jsp

        对应第三点中的setLoginUrl("/redirectToLogin");

    @GetMapping("/redirectToLogin")
    public ResponseEntity redirectToLogin(){
        return new ResponseEntity<>("Please log on first", HttpStatus.FORBIDDEN);
    }

5、用户登录登出UserController

    @GetMapping(value = "/login")
    public ResponseEntity login(@RequestParam String userName, @RequestParam String passWord) {

        SysUser sysUser = sysUserService.getUserByName(userName);
        if (sysUser == null) {
            return error(401, "username/password err");
        } else {
            String dbPassWord = sysUser.getPassWord();
            if (passWord.equals(dbPassWord)) {
                Subject subject = SecurityUtils.getSubject();
                subject.logout();
                UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userName, passWord);
                subject.login(usernamePasswordToken);
                Session session = subject.getSession();
                //设置session过期时间,负数为永不过期
                session.setTimeout(60 * 60 * 1000);
                Serializable tokenId = session.getId();
                return success(tokenId);
            } else {
                return error(401, "username/password err");
            }
        }
    }

    @GetMapping(value = "/logout")
    public ResponseEntity login() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return success();
    }

至此,spring boot-shiro已经完成整合运行了,可以完成用户登录,鉴权操作了。在此基础上还可以处理一下权限不足异常,做一个统一返回。这个全局异常处理还可以处理其他异常,起到一个和统一返回的作用。

@ControllerAdvice
public class GlobalExceptionHandler {

    @ResponseBody
    @ExceptionHandler(value = AuthorizationException.class)
    public ResponseEntity authorizationExceptionHandler(HttpServletRequest httpServletRequest, AuthorizationException e) {
        logger.info("AuthorizationException:" + e.getMessage());
        return new ResponseEntity<>("AuthorizationException", HttpStatus.UNAUTHORIZED);
    }
}

你可能感兴趣的:(shiro,spring,boot)