• SpringBoot2.0与Shrio集成实战操作


    1、创建springboot项目

    2、添加相关依赖

    thymeleaf、shrio等依赖

    <dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.1</version>
    </dependency>
    <dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.4.1</version>
    </dependency>

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    </dependency>

    3、添加Shrio配置类

    ShiroConfig.java

    package com.chlin.springbootshrio.config;

    import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
    import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
    import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
    import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
    import org.apache.shiro.mgt.SecurityManager;

    import java.util.LinkedHashMap;
    import java.util.Map;
    import java.util.Properties;

    /**
    * @ desc:
    * @ Author :chenhl01.
    * @ Date :Created in 10:18 2019/7/18
    */
    @Configuration
    public class ShiroConfig {

    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
    System.out.println("ShiroConfiguration.shirFilter()");
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    shiroFilterFactoryBean.setSecurityManager(securityManager);
    //拦截器.
    Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
    // 配置不会被拦截的链接 顺序判断,因为前端模板采用了thymeleaf,这里不能直接使用 ("/static/**", "anon")来配置匿名访问,必须配置到每个静态目录
    filterChainDefinitionMap.put("/css/**", "anon");
    filterChainDefinitionMap.put("/fonts/**", "anon");
    filterChainDefinitionMap.put("/img/**", "anon");
    filterChainDefinitionMap.put("/js/**", "anon");
    filterChainDefinitionMap.put("/html/**", "anon");
    //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
    filterChainDefinitionMap.put("/logout", "logout");
    //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
    //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
    filterChainDefinitionMap.put("/**", "authc");
    // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
    shiroFilterFactoryBean.setLoginUrl("/login");
    // 登录成功后要跳转的链接
    shiroFilterFactoryBean.setSuccessUrl("/index");

    //未授权界面;
    shiroFilterFactoryBean.setUnauthorizedUrl("/403");
    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
    return shiroFilterFactoryBean;
    }

    /**
    * 凭证匹配器
    * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
    * )
    * @return
    */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
    HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
    hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
    hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5(""));
    return hashedCredentialsMatcher;
    }

    @Bean
    public MyShiroRealm myShiroRealm(){
    MyShiroRealm myShiroRealm = new MyShiroRealm();
    myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
    return myShiroRealm;
    }


    @Bean
    public SecurityManager securityManager(){
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    securityManager.setRealm(myShiroRealm());
    return securityManager;
    }

    /**
    * 开启shiro aop注解支持.
    * 使用代理方式;所以需要开启代码支持;
    * @param securityManager
    * @return
    */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
    AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
    authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
    return authorizationAttributeSourceAdvisor;
    }

    @Bean(name="simpleMappingExceptionResolver")
    public SimpleMappingExceptionResolver
    createSimpleMappingExceptionResolver() {
    SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
    Properties mappings = new Properties();
    mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
    mappings.setProperty("UnauthorizedException","/user/403");
    r.setExceptionMappings(mappings); // None by default
    r.setDefaultErrorView("error"); // No default
    r.setExceptionAttribute("exception"); // Default is "exception"
    //r.setWarnLogCategory("example.MvcLogger"); // No default
    return r;
    }

    }

    MyShiroRealm.java
    package com.chlin.springbootshrio.config;

    import com.chlin.springbootshrio.entity.SysPermission;
    import com.chlin.springbootshrio.entity.SysRole;
    import com.chlin.springbootshrio.entity.User;
    import com.chlin.springbootshrio.service.IUserService;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.SimpleAuthenticationInfo;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.apache.shiro.util.ByteSource;

    import javax.annotation.Resource;

    /**
    * @ desc:
    * @ Author :chenhl01.
    * @ Date :Created in 10:12 2019/7/18
    */
    public class MyShiroRealm extends AuthorizingRealm {
    @Resource
    private IUserService userService;

    //权限信息,包括角色以及权限
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()");
    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    //如果身份认证的时候没有传入User对象,这里只能取到userName
    //也就是SimpleAuthenticationInfo构造的时候第一个参数传递需要User对象
    User user = (User) principals.getPrimaryPrincipal();

    for (SysRole role : user.getRoleList()) {
    authorizationInfo.addRole(role.getRole());
    for (SysPermission p : role.getPermissions()) {
    authorizationInfo.addStringPermission(p.getPermission());
    }
    }
    return authorizationInfo;
    }

    /*主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
    throws AuthenticationException {
    System.out.println("MyShiroRealm.doGetAuthenticationInfo()");
    //获取用户的输入的账号.
    String userName = (String) token.getPrincipal();
    System.out.println(token.getCredentials());
    //通过username从数据库中查找 User对象.
    //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
    User user = userService.findByUserName(userName);
    System.out.println("----->>user=" + user);
    if (user == null) {
    return null;
    }
    SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
    user, //这里传入的是user对象,比对的是用户名,直接传入用户名也没错,但是在授权部分就需要自己重新从数据库里取权限
    user.getPassword(), //密码
    ByteSource.Util.bytes(user.getCredentialsSalt()),//salt=username+salt
    getName() //realm name
    );
    return authenticationInfo;
    }

    }

    4、登录逻辑部分代码

    UsernamePasswordToken token = new UsernamePasswordToken(userName, password);

    // 4、认证
    try {
    currentUser.login(token);// 传到MyAuthorizingRealm类中的方法进行认证
    Session session = currentUser.getSession();
    session.setAttribute("userName", userName);
    loginResult.setLogin(true);
    return loginResult;
    } catch (UnknownAccountException e) {
    e.printStackTrace();
    msg = "UnknownAccountException -- > 账号不存在:";
    } catch (IncorrectCredentialsException e) {
    msg = "IncorrectCredentialsException -- > 密码不正确:";
    } catch (AuthenticationException e) {
    e.printStackTrace();
    msg = "用户验证失败";
    }

    currentUser.login()方法执行MyShiroRealm中的doGetAuthenticationInfo来进行用户认证


    项目地址:https://github.com/chlin7/springboot-shrio.git
  • 相关阅读:
    sql批量生成showdocs数据字典的md文档
    kis注册账套的时候选不到数据
    kis中导入其它账套的科目
    sql server查询某个字段的类型
    sql server修改默认值语句
    k3 cloud查询关联关系
    k3 cloud中根据表明查找业务对象
    计算机系统要素(存储器)
    计算机系统要素(多路复用器)
    领域设计:聚合与聚合根
  • 原文地址:https://www.cnblogs.com/lovechengyu/p/11203077.html
Copyright © 2020-2023  润新知