Shiro 权限控制

Shiro 概念

提供认证、授权session管理加密等功能的权限框架

Shiro系统交互流程

subject——>SecurityManage——>认证器——>realm

Shiro认证

认证原理

subject.login——>SecurityManager——>realm——>访问db,验证登录用户

过滤器

三个重要的过滤器

  1. anon 免认证过滤器
  2. authc 认证过滤器
  3. perms 授权过滤器

    认证实现

    shiro 依赖包

    1. <dependency>
    2. <groupId>org.apache.shiro</groupId>
    3. <artifactId>shiro-spring</artifactId>
    4. <version>1.9.0</version>
    5. </dependency>

    创建 ShiroRealm

    1. public class ShiroRealm extends AuthorizingRealm {
    2. //授权校验方法
    3. @Override
    4. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    5. return null;
    6. }
    7. //认证方法
    8. @Override
    9. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    10. return null;
    11. }
    12. }

    编写配置类 ShiroCofig

    ```java @Configuration public class ShiroConfig { // 1.创建realm,加入ioc容器 @Bean public ShiroRealm shiroRealm() {

    1. ShiroRealm shiroRealm = new ShiroRealm();
    2. return shiroRealm;

    }

    //创建securityManager对象,注入realm @Bean public SecurityManager securityManager(ShiroRealm shiroRealm) {

    1. DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(shiroRealm);
    2. return securityManager;

    }

    @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {

    1. //创建过滤工厂
    2. ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
    3. //设置securityManager安全管理对象
    4. factoryBean.setSecurityManager(securityManager);
    5. //设置登录页面的地址,当没有认证或认证失败的时候自动跳转到该页面
    6. factoryBean.setLoginUrl("Login.html");
    7. //授权校验失败,默认跳转搭配该页面
    8. factoryBean.setUnauthorizedUrl("unauthorizedUrl.html");
    9. //存储放行的资源、认证的资源
    10. Map<String, String> map = new HashMap<>();
    11. //匿名访问过滤器
    12. map.put("login", "anon");
    13. map.put("login.html", "anon");
    14. //authc 认证过滤器,访问/**所有的资源都需要认证,除了放行的
    15. map.put("/**", "authc");
  1. factoryBean.setFilterChainDefinitionMap(map);
  2. return factoryBean;
  3. }

}

  1. <a name="Zj9TW"></a>
  2. ### LoginController 认证
  3. ```java
  4. @RestController
  5. @Slf4j
  6. @Api(tags = "登录认证")
  7. public class LoginController {
  8. @PostMapping("/login")
  9. @ApiOperation(value = "认证方法")
  10. public R<String> login(@RequestBody Users users) {
  11. try {
  12. //获取subject对象
  13. Subject subject = SecurityUtils.getSubject();
  14. //创建token,封装用户输入的账号密码
  15. AuthenticationToken token = new UsernamePasswordToken(users.getName(), users.getPassword());
  16. //登录认证,自动渠道realm的认证方法
  17. subject.login(token);
  18. log.info("登录认证成功,身份信息:{}", subject.getPrincipal());
  19. return R.ok("登录认证成功");
  20. } catch (AuthenticationException e) {
  21. e.printStackTrace();
  22. log.error("认证失败,{}", e.getMessage());
  23. }
  24. return R.fail("认证失败");
  25. }

ShiroRealm 实现认证

  1. @Slf4j
  2. public class ShiroRealm extends AuthorizingRealm {
  3. @Resource
  4. private UserService userService;
  5. //认证方法 被subject.login()调用
  6. @Override
  7. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
  8. //获取用户输入的用户名
  9. String name = (String) token.getPrincipal();
  10. //根据用户名查询
  11. Users users = userService.findByName(name);
  12. //判断
  13. if (name == null) {
  14. log.error("用户名不存在,{}", name);
  15. return null;
  16. }
  17. //获取数据库中正确的密码
  18. String correctPwd = users.getPassword();
  19. //返回
  20. //参数1
  21. return new SimpleAuthenticationInfo(users, correctPwd, this.getName());
  22. }
  23. }

退出方法

  1. @RestController
  2. @Slf4j
  3. @Api(tags = "登录认证")
  4. public class LoginController {
  5. @GetMapping("/logout")
  6. @ApiOperation(value = "退出方法")
  7. public R<String> login() {
  8. SecurityUtils.getSubject().logout();
  9. return R.ok("退出成功");
  10. }
  11. }

Shiro认证加密

Md5+用户名加密

修改表中的用户密码为加盐加密后的结果

自动对用户输入的密码加密