安全架构
加密
分类
- 可逆加密和不可逆加密 
  
- 不可逆加密:常见的不可逆加密算法有MD5,HMAC,SHA1、SHA-224、SHA-256、SHA-384,和SHA-512,其中SHA-224、SHA-256、SHA-384;
 
 - 可逆加密分为对称加密和非对称加密 
  
- 通过密钥进行加密;
 - 对称加密:加密和解密使用同一个密钥,使用该密钥可以获取原密码;
 - 非对称加密:加密通过公钥,解密通过私钥;公钥可以公开给别人进行加密,私钥永远在自己手里,非常安全,黑客拦截也没用,因为私钥未公开。著名的RSA加密算法用的就是非对称加密。
 
 
JWT
https://blog.csdn.net/weixin_45070175/article/details/118559272
-  
JWT(JSON Web Token)是一种常用的非对称加密规范
 -  
JWT组成:头部、负载、签名三部分组成,所以标准jwt格式为:xxx.zzz.yyyyyyy
-  
1.头部(Base64加密成字符串):描述jwt的基本信息;包括typ、alg { 'typ':'JWT' #类型 'alg':'HS256' #算法 } 2.负载(Base64加密成字符串):存放有效信息的部分,一般携带时间以方便验证token是否过期失效; 3.签名(通过头部的加密算法进行组合加密):头部(Base64加密成字符串)、负载(Base64加密成字符串)加上盐(secret)组合加密成为的第三部分;由于只有盐是服务器自定义的,所以一定要保密盐,防止客户端自己创建jwt; -  
  
 -  
 -  
类型:
nonsecure JWT:未经过签名,不安全的JWT;JWS:经过签名的JWT;JWE:payload部分经过加密的JWT
 -  
java支持(jwt、jjwt等
-  
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> -  
//对称加密解密 //加密 @Test void contextLoads() { JwtBuilder jwtBuilder = Jwts.builder() //设置jti .setId("111") //设置签发事件 .setIssuedAt(new Date()) //设置编码格式和盐 .signWith(SignatureAlgorithm.HS256,"xxxx") //设置过期时间为1分钟后 .setExpiration(new Date(live)); //生成token String token = jwtBuilder.compact(); System.out.println(token); } //解密 @Test void contextLoads() { Claims claims = Jwts.parser().setSigningKey("xxxx")//设置盐 .parseClaimsJws(token).getBody();//输入token System.out.println("id"+claims.getId()+"time"+claims.getIssuedAt());//解析数据 } //非对称加密 
 -  
 
JWT认证流程
 
Shrio
快速入门
基础知识
 Shiro是一个强大且易用的Java安全框架,能够用于身份验证、授权、加密和会话管理。Shiro拥有易于理解的API,您可以快速、轻松地获得任何应用程序——从最小的移动应用程序到最大的网络和企业应用程序。
特点
- 易于使用
 - 全面:不需要依赖其他框架,而且可以集成在其他框架上;
 - 灵活:可以在多种应用环境下使用,包括但不限于web和EJB等
 - 低耦合和web支持等
 
功能架构

**Authentication(认证), Authorization(授权), Session Management(会话管理), Cryptography(加密)**被 Shiro 框架的开发团队称之为应用安全的四大基石。
- Authentication:用户身份鉴别(即登录)
 - Authorization:访问控制(权限控制),比如某一个用户是否具有某一操作的使用权限
 - Session Management:特定用户的会话管理,可以用于单点登录等
 - Cryptography:在数据源处对于数据进行加密;
 
辅助功能支持
- web Support:显然是对于web支持
 - caching:缓存是Apache Shiro API中的第一级,以确保安全操作保持快速和高效。
 - Concurrent:并发操作的支持
 - “记住我”和“以…运行”
 
组件架构

三大组件:Subject、Shiro SecurityManager、Realm
- Subject:当前用户,Subject 可以是一个人,但也可以是第三方服务、守护进程帐户、时钟守护任务或者其它–当前和软件交互的任何事件。
 - Shiro SecurityManager:管理所有Subject,SecurityManager 是 Shiro 架构的核心,配合内部安全组件共同组成安全伞。
 - Realm:用于进行权限信息的验证,我们自己实现。**Realm 本质上是一个特定的安全 DAO:它封装与数据源连接的细节,得到Shiro 所需的相关的数据。**在配置 Shiro 的时候,你必须指定至少一个Realm 来实现认证(authentication)和/或授权(authorization)。
 
认证的过程

- 首先获取到代表用户的Subject,将账号密码封装到UsernamePasswordToken得到token,然后调用login进入安全管理器;
 - 然后通过安全管理器调用Reaml;
 - 再然后自定义Reaml进行权限认证;
 - 最后可以通过logout退出认证;
 
使用

    @PostMapping("/login")
    public String login(String adminName, String password){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户登录信息
        UsernamePasswordToken token = new UsernamePasswordToken(adminName,password);
        try{
            //执行登录方法
            subject.login(token);
            //登录成功……,跳转helloworld页面
            return "helloworld";
        }catch (UnknownAccountException e){
            //用户名不存在
            model.addAttribute("msg","管理员名错误");
            return "index";
        }catch (IncorrectCredentialsException e){
            //密码不存在
            model.addAttribute("msg","密码错误");
            return "index";
        }
    }
 
快速开始
-  
自定义Reaml
//首先继承AuthorizingRealm //重写俩个方法:授权和认证 public class MyReaml entends AuthorizingRealm { //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { //…… } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //…… } } -  
密码加密
SimpleHash:Shiro自带的MD5加密算法
BCrypt:spring的加密算法
//BCrypt加解密 public final class BcrypUtil { /** * 加密 * @param password * @return */ public static String encode(String password){ return BCrypt.hashpw(password, BCrypt.gensalt()); } /** * 密码校验 * @param password * @param encodePassword * @return */ public static boolean match(String password, String encodePassword){ return BCrypt.checkpw(password, encodePassword); } } -  
注册到SpringBoot
- 注册默认的AuthorizingRealm(认证领域)、SecurityManager(安全管理器)、SimpleCredentialsMatcher(密码管理器)、ShiroFilterFactoryBean(校验规则)
 
 
//通过@Configuration类+@Bean注册bean
@Configuration
public class ShiroConfig {
	//重写校验规则的时候自带注册
    @Autowired
    private SecurityMatcher matcher;
    
    
    /**
     * 首先书Reaml
     * 身份认证 Realm
     * @return
     */
    @Bean
    public UserRealm userRealm(){
        UserRealm userRealm = new UserRealm();
        userRealm.setAuthenticationTokenClass(AuthenticationToken.class);
        userRealm.setCredentialsMatcher(校验器);
        return userRealm;
    }
    
    /**
     * 安全管理器
     * @param userRealm
     * @return
     */
    @Bean(name = "defaultWebSecurityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        //关联UserRealm
        defaultWebSecurityManager.setRealm(userRealm());
        return defaultWebSecurityManager;
    }
    
    /**
     * 过滤器工厂(配置过滤规则)
     * @param defaultWebSecurityManager
     * @return
     */
    @Bean(name = "shiroFilterFactoryBean")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(){
      /**
       * anon:无需校验就可以访问
       * authc:登录才可以访问
       * user:“记住我才可以访问”
       * perms:拥有对于某一资源访问权限才可以访问
       * role:拥有某一角色权限才可以访问
       */
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(getDefaultWebSecurityManager());
        //添加shiro的内置过滤器,配置拦截规则
        Map<String,String> filterMap = new LinkedHashMap<>();
        filterMap.put("/swagger**/**","anon");//无需登录
        filterMap.put("/v3/**","anon");
        filterMap.put("/doc.html","anon");
        filterMap.put("/admin/login","anon");
        filterMap.put("/admin/addAdmin","roles[root]");//拥有root权限
        filterMap.put("/admin/**","authc");//需要登录
        //将自定义规则设置为过滤器的规则
        bean.setFilterChainDefinitionMap(filterMap);
        //配置无权限时跳转登录页面的位置(或者处理方式)
        bean.setLoginUrl("/toLogin");
        return bean;
    }
    /**
     * thymeleaf整合shiro
     */
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
}
@Compoment
public class SecurityMatcher extends SimpleCredentialsMatcher {
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        //前端传来的密码
        UsernamePasswordToken admin = (UsernamePasswordToken) token;
        String password = new String(admin.getPassword());
        //数据库中查询出的加密后的密码
        String encodePassword = (String) info.getCredentials();
        //密码比较
        return BcrypUtil.match(password, encodePassword);
    }
}
 
组件
Subject和SecurityUtils
- Subject:**单个应用程序用户的状态和安全操作。这些操作包括身份验证(登录/注销)、授权(访问控制)和会话访问。**它是 Shiro 用于单用户安全功能的主要机制。
 - SecurityUtils:静态工具类,可以通过其getSubject获取当前访问(线程的Subject)
 
前面我们在使用的时候已经知道Subject仅仅通过一个login方法即可以实现登录验证;
Realm
SecurityManager
- SecurityManager:安全管理器,对全部的subject进行安全管理, 它是shiro的核心,负责对所有的subject进行安全管理。 SecurityManager调用调用shiro的各个最核心组件,连接当前请求和其他核心组件进行交互(授权、认证、session、crash等) 
  
 -  
 - 实现体系*(其实现类似docker,层层嵌套,功能层层扩展)* 
  
 
Authenticator和Authorizer
- Authenticator即认证器,对用户身份进行认证,shiro提供ModularRealmAuthenticator实现类,通过 ModularRealmAuthenticator基本上可以满足大多数需求,也可以 自定义认证器。
 - Authorizer即授权器,用户通过认证器认证通过,在访问功能时 需要通过授权器判断用户是否有此功能的操作权限。
 
 


















