zoukankan      html  css  js  c++  java
  • Shiro登录认证

    一、登录认证

      即在应用中谁能证明他就是他本人。一般提供如他们的身份ID 一些标识信息来表明他就是他本人,如提供身份证,用户名/密码来证明。

      在 shiro 中,用户需要提供principals (身份)和credentials(证明)给shiro,从而应用能验证用户身份。

    二、Shiro登录认证基本概念

    1,principals

      身份,即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。

      一个主体可以有多个principals,但只有一个Primary principals,一般是用户名/密码/手机号。

    2, credentials

      证明/凭证,即只有主体知道的安全值,如密码/数字证书等。

      最常见的principals和credentials组合就是用户名/密码了。接下来先进行一个基本的身份认证。

    三、Shiro登录认证流程

    1、首先调用Subject.login(token)进行登录,其会自动委托给Security Manager,调用之前必须通过SecurityUtils. setSecurityManager()设置;

    2、SecurityManager负责真正的身份验证逻辑;它会委托给Authenticator进行身份验证;

    3、Authenticator才是真正的身份验证者,Shiro API中核心的身份认证入口点,此处可以自定义插入自己的实现;

    4、Authenticator可能会委托给相应的AuthenticationStrategy进行多Realm身份验证,默认ModularRealmAuthenticator会调用AuthenticationStrategy进行多Realm身份验证;

    5、Authenticator 会把相应的token 传入Realm,从Realm 获取身份验证信息,如果没有返回/抛出异常表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进行访问。

     四、Shiro在SpringBoot中Demo

    Config.java

     1 package io.guangsoft.shiro.config;
     2 
     3 import java.util.LinkedHashMap;
     4 import java.util.Map;
     5 
     6 import io.guangsoft.shiro.realm.Realm;
     7 import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
     8 import org.apache.shiro.mgt.RememberMeManager;
     9 import org.apache.shiro.mgt.SecurityManager;
    10 import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
    11 import org.apache.shiro.web.mgt.CookieRememberMeManager;
    12 import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
    13 import org.apache.shiro.web.servlet.SimpleCookie;
    14 import org.springframework.context.annotation.Bean;
    15 import org.springframework.context.annotation.Configuration;
    16 
    17 @Configuration
    18 public class Config {
    19 
    20     @Bean
    21     public Realm realmManager() {
    22         // 加密相关
    23         HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
    24         // 散列算法
    25         hashedCredentialsMatcher.setHashAlgorithmName("md5");
    26         // 散列次数
    27         hashedCredentialsMatcher.setHashIterations(2);
    28         Realm realm = new Realm();
    29         realm.setCredentialsMatcher(hashedCredentialsMatcher);
    30         return realm;
    31     }
    32 
    33     @Bean
    34     public RememberMeManager rememberMeManager() {
    35         CookieRememberMeManager rememberMeManager = new CookieRememberMeManager();
    36         //注入自定义cookie(主要是设置寿命, 默认的一年太长)
    37         SimpleCookie simpleCookie = new SimpleCookie();
    38         simpleCookie.setHttpOnly(true);
    39         //设置RememberMe的cookie有效期为7天
    40         simpleCookie.setMaxAge(604800);
    41         rememberMeManager.setCookie(simpleCookie);
    42         return rememberMeManager;
    43     }
    44 
    45     @Bean
    46     public SecurityManager securityManager() {
    47         DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    48         securityManager.setRealm(realmManager());
    49         securityManager.setRememberMeManager(rememberMeManager());
    50         return securityManager;
    51     }
    52 
    53     @Bean
    54     public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
    55         ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    56         shiroFilterFactoryBean.setSecurityManager(securityManager);
    57         //当用户未登录则跳转到登录路径
    58         shiroFilterFactoryBean.setLoginUrl("/login");
    59         //登录成功后要跳转的链接,表单登录方式有效
    60         shiroFilterFactoryBean.setSuccessUrl("/index");
    61         //未授权界面,指定没有权限操作时跳转页面
    62         shiroFilterFactoryBean.setUnauthorizedUrl("/warning");
    63         //配置不会被过滤的链接顺序判断,过虑器链定义,从上向下顺序执行,一般将/**放在最下边
    64         Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
    65         //对静态资源设置匿名访问,anon:所有url都可以匿名访问
    66         filterChainDefinitionMap.put("/assets/**", "anon");
    67         //放开登录接口,允许进行登录操作
    68         filterChainDefinitionMap.put("/shiro/login", "anon");
    69         //配置退出过滤器,其中的具体的退出代码Shiro已经替我们实现了
    70         filterChainDefinitionMap.put("/shiro/logout", "logout");
    71         //authc:所有url都必须认证通过才可以访问
    72         filterChainDefinitionMap.put("/**", "authc");
    73         shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
    74         return shiroFilterFactoryBean;
    75     }
    76 
    77 }

    Realm.java

     1 package io.guangsoft.shiro.realm;
     2 
     3 import org.apache.shiro.authc.AuthenticationException;
     4 import org.apache.shiro.authc.AuthenticationInfo;
     5 import org.apache.shiro.authc.AuthenticationToken;
     6 import org.apache.shiro.authc.SimpleAuthenticationInfo;
     7 import org.apache.shiro.authz.AuthorizationInfo;
     8 import org.apache.shiro.authz.SimpleAuthorizationInfo;
     9 import org.apache.shiro.realm.AuthorizingRealm;
    10 import org.apache.shiro.subject.PrincipalCollection;
    11 import org.apache.shiro.util.ByteSource;
    12 
    13 import java.util.ArrayList;
    14 import java.util.List;
    15 
    16 public class Realm extends AuthorizingRealm {
    17 
    18         //认证,模拟从数据库查询出密码
    19     @Override
    20    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    21         String userName = (String) token.getPrincipal();
    22         String password = "4d521acb9b8b3b4fa082ab16b3bd363a";
    23         String salt = "guanghe";
    24         return new SimpleAuthenticationInfo(userName, password, ByteSource.Util.bytes(salt), this.getName());
    25     }
    26 }

    ShiroController.java

     1 package io.guangsoft.shiro.controller;
     2 
     3 import com.alibaba.fastjson.JSONObject;
     4 import org.apache.shiro.SecurityUtils;
     5 import org.apache.shiro.authc.*;
     6 import org.apache.shiro.subject.Subject;
     7 import org.springframework.web.bind.annotation.RequestMapping;
     8 import org.springframework.web.bind.annotation.RestController;
     9 
    10 @RestController
    11 @RequestMapping("shiro")
    12 public class ShiroController {
    13 
    14     @RequestMapping(value = "login")
    15     public String login(String username, String password, Boolean rememberMe) {
    16         Subject subject = SecurityUtils.getSubject();
    17         UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
    18         usernamePasswordToken.setRememberMe(rememberMe);
    19         String msg = null;
    20         try {
    21             subject.login(usernamePasswordToken);
    22             msg = "身份认证成功!";
    23         } catch (UnknownAccountException e) {
    24             e.printStackTrace();
    25             msg = "账号不存在!";
    26         } catch (LockedAccountException e) {
    27             e.printStackTrace();
    28             msg = "账号被锁定!";
    29         } catch (DisabledAccountException e) {
    30             e.printStackTrace();
    31             msg = "账号被禁用!";
    32         } catch (IncorrectCredentialsException e) {
    33             e.printStackTrace();
    34             msg = "凭证/密码错误!";
    35         } catch (ExpiredCredentialsException e) {
    36             e.printStackTrace();
    37             msg = "凭证/密码过期!";
    38         } catch (ExcessiveAttemptsException e) {
    39             e.printStackTrace();
    40             msg = "登录失败次数过多!";
    41         }
    42         JSONObject result = new JSONObject();
    43         if(subject.isAuthenticated()) {
    44             result.put("code", 0);
    45         } else {
    46             result.put("code", -1);
    47         }
    48         result.put("msg", msg);
    49         return result.toString();
    50     }
    51 }
  • 相关阅读:
    WPF 中英文切换
    System.Data.Entity.Core.ProviderIncompatibleException:0x89c50107
    WinForm使用原生gdi+绘制自定义曲线图、折线图
    C#使用EPPlus读写excel
    ICSharpCode.SharpZipLib C# 压缩文件夹SharpZipHelper
    C# XSLT 转换word 生成word
    代码生成器集合
    优秀的个人博客
    面试经典复习资料
    图解算法
  • 原文地址:https://www.cnblogs.com/guanghe/p/10688176.html
Copyright © 2011-2022 走看看