首页 > 电脑常识 > 运维

使用SpringBoot+shiro完成简单的登录认证

admin 运维 2021-04-26 15:57:18 spring  
后台-系统设置-扩展变量-手机广告位-内容正文底部

新建项目

添加json、aop、shiro的相关依赖

<!--Alijson插件 -->

      <dependency>

          <groupId>com.alibaba</groupId>

          <artifactId>fastjson</artifactId>

          <version>1.2.54</version>

      </dependency>

      <!-- shiro -->

      <dependency>

         <groupId>org.springframework.boot</groupId>

          <artifactId>spring-boot-starter-aop</artifactId>

      </dependency>

      <dependency>

          <groupId>org.apache.shiro</groupId>

          <artifactId>shiro-core</artifactId>

          <version>1.4.0</version>

      </dependency>

      <dependency>

          <groupId>org.apache.shiro</groupId>

          <artifactId>shiro-spring</artifactId>

          <version>1.4.0</version>

      </dependency>

<dependency>

          <groupId>org.projectlombok</groupId>

          <artifactId>lombok</artifactId>

          <optional>true</optional>

      </dependency>

添加application配置

 

spring.datasource.url=jdbc:mysql://localhost:3306/xiangmu

spring.datasource.username=root

spring.datasource.password=123456

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

 

mybatis.typeAliasesPackage=com.zjz.entity

mybatis.mapperLocations=classpath:mapper/*.xml

 

shiro的配置

package com.zjz.config;

 

import java.util.LinkedHashMap;

import java.util.Properties;

 

import org.apache.shiro.mgt.SecurityManager;

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.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

 

 

 

 

@Configuration

public class ShiroConfig {

     

      /**

       * 解决setUnauthorizedUrl不能跳转的问题

       */

      @Bean

    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {

        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();

        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);

        return authorizationAttributeSourceAdvisor;

    }

     

      /**

       * shiro的过滤器ShiroFilterFactoryBean,

       */

      @Bean

      public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {

           

            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

           

            // Shiro的核心安全接口

            shiroFilterFactoryBean.setSecurityManager(securityManager);

           

            //没有登录发送请求时设置跳转到登录

            shiroFilterFactoryBean.setLoginUrl("/test");

           

            //访问没有权限的接口跳转的接口

            //shiroFilterFactoryBean.setUnauthorizedUrl("/notPer");

           

            //自定义过滤链,使用LinkedHashMap保证有序

            LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();

           

            /*

             * 配置拦截规则,anon 表示资源都可以匿名访问

             * authc:登录后能访问

             */

        filterChainDefinitionMap.put("/public/**", "anon");

        //其他资源都需要认证

        filterChainDefinitionMap.put("/**", "authc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

       

       

            return shiroFilterFactoryBean;

           

      }

     

      /**

       * Shiro的核心安全接口

       */

      @Bean

      public SecurityManager securityManager() {

           

            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

           

            securityManager.setRealm(customRealm());

           

           

            return securityManager;

           

      }

     

      /**

       * 自定义realm

       */

      @Bean

      public CustomRealm customRealm() {

           

            return new CustomRealm();

      }

     

     

  

    @Bean

    public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {

        SimpleMappingExceptionResolver simpleMappingExceptionResolver=new SimpleMappingExceptionResolver();

        Properties properties=new Properties();

        properties.setProperty("org.apache.shiro.authz.UnauthorizedException","/index/unauthorized");

        properties.setProperty("org.apache.shiro.authz.UnauthenticatedException","/index/unauthorized");

        simpleMappingExceptionResolver.setExceptionMappings(properties);

        return simpleMappingExceptionResolver;

    }

   

   

    @Bean

    public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {

 

        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();

        defaultAdvisorAutoProxyCreator.setUsePrefix(true);

 

        return defaultAdvisorAutoProxyCreator;

    }

   

    @Bean

    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){

        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();

        advisorAutoProxyCreator.setProxyTargetClass(true);

        return advisorAutoProxyCreator;

    }

}

 

 

package com.zjz.config;

 

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.springframework.beans.factory.annotation.Autowired;

 

import com.zjz.entity.Users;

import com.zjz.service.UsersService;

 

public class CustomRealm extends AuthorizingRealm {

 

      @Autowired

      private UsersService userInfoService;

       ;

 

      /**

       * 授权

       */

      @Override

      protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

            System.out.println("执行了授权");

            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

            return simpleAuthorizationInfo;

      }

 

      /**

       * 认证

       */

      @Override

      protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)

                  throws AuthenticationException {

            System.out.println("执行了认证");

 

            String loginname = (String) authenticationToken.getPrincipal();

 

            Users user = userInfoService.getByUserName(loginname);

 

            if (user == null) {

                 

                  return null;

            } else {

                  SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(),

                              getName());

                  System.out.println("users!=null" + simpleAuthenticationInfo);

                  return simpleAuthenticationInfo;

            }

      }

}

 

package com.zjz.config;

 

import java.io.IOException;

 

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.springframework.context.annotation.Configuration;

import org.springframework.stereotype.Component;

 

@Component

@Configuration

public class CORSFilter implements Filter {

 

    @Override

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {

        HttpServletResponse response = (HttpServletResponse) servletResponse;

        HttpServletRequest request = (HttpServletRequest) servletRequest;

        // 允许哪些Origin发起跨域请求

        String orgin = request.getHeader("Origin");

        // response.setHeader( "Access-Control-Allow-Origin", config.getInitParameter( "AccessControlAllowOrigin" ) );

        response.setHeader( "Access-Control-Allow-Origin", orgin );

        // 允许请求的方法

        response.setHeader( "Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,PUT" );

        //多少秒内,不需要再发送预检验请求,可以缓存该结果

        response.setHeader( "Access-Control-Max-Age", "3600" );

        // 表明它允许跨域请求包含xxx头

        response.setHeader( "Access-Control-Allow-Headers", "x-auth-token,Origin,Access-Token,X-Requested-With,Content-Type, Accept" );

        //是否允许浏览器携带用户身份信息(cookie)

        response.setHeader( "Access-Control-Allow-Credentials", "true" );

        //prefight请求

        if (request.getMethod().equals( "OPTIONS" )) {

            response.setStatus( 200 );

            return;

        }

        chain.doFilter( servletRequest, response );

    }

 

}

 

package com.zjz.util;

 

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.util.Random;

 

import org.apache.shiro.codec.Hex;

 

public class MD5Util {

 

         /**

          * 普通MD5加密<br> 

          *  

          * @param input

          * @return

          */

        public static String MD5(String input) { 

            MessageDigest md5 = null; 

            try { 

                md5 = MessageDigest.getInstance("MD5"); 

            } catch (NoSuchAlgorithmException e) { 

                return "check jdk"; 

            } catch (Exception e) { 

                e.printStackTrace(); 

                return ""; 

            } 

            char[] charArray = input.toCharArray(); 

            byte[] byteArray = new byte[charArray.length]; 

     

            for (int i = 0; i < charArray.length; i++) 

                byteArray[i] = (byte) charArray[i]; 

            byte[] md5Bytes = md5.digest(byteArray); 

            StringBuffer hexValue = new StringBuffer(); 

            for (int i = 0; i < md5Bytes.length; i++) { 

                int val = ((int) md5Bytes[i]) & 0xff; 

                if (val < 16) 

                    hexValue.append("0"); 

                hexValue.append(Integer.toHexString(val)); 

            } 

            return hexValue.toString(); 

     

        } 

      

          

          

          

            /**

             * 加盐MD5加密<br>

             *

             * @param password

             * @return

             */

            public static String getMD5(String password) { 

                Random r = new Random(); 

                StringBuilder sb = new StringBuilder(16); 

                sb.append(r.nextInt(99999999)).append(r.nextInt(99999999)); 

                int len = sb.length(); 

                if (len < 16) { 

                    for (int i = 0; i < 16 - len; i++) { 

                        sb.append("0"); 

                    } 

                } 

                String salt = sb.toString(); 

                password = md5Hex(password + salt); 

                char[] cs = new char[48]; 

                for (int i = 0; i < 48; i += 3) { 

                    cs[i] = password.charAt(i / 3 * 2); 

                    char c = salt.charAt(i / 3); 

                    cs[i + 1] = c; 

                    cs[i + 2] = password.charAt(i / 3 * 2 + 1); 

                } 

                return new String(cs); 

            } 

     

            /**

             * 校验加盐后是否和原文一致<br>

             *  

             * @param password

             * @param md5

             * @return

             */

            public static boolean verify(String password, String md5) { 

               try {

                   char[] cs1 = new char[32]; 

                    char[] cs2 = new char[16]; 

                    for (int i = 0; i < 48; i += 3) { 

                        cs1[i / 3 * 2] = md5.charAt(i); 

                        cs1[i / 3 * 2 + 1] = md5.charAt(i + 2); 

                        cs2[i / 3] = md5.charAt(i + 1); 

                    } 

                    String salt = new String(cs2); 

                    return md5Hex(password + salt).equals(new String(cs1)); 

               } catch (Exception e) {

                   return false;

               }

               

            } 

     

            /** 

             * 获取十六进制字符串形式的MD5摘要 

             */ 

            private static String md5Hex(String src) { 

                try { 

                    MessageDigest md5 = MessageDigest.getInstance("MD5"); 

                    byte[] bs = md5.digest(src.getBytes()); 

                    return new String(new Hex().encode(bs)); 

                } catch (Exception e) { 

                    return null; 

                } 

            } 

     

          

          

    }

4写控制器

使用hbuilder新建web项目

提供一个js文件

  1. var globalData = {
  2. server: "http://localhost:8080/",
  3. pre: "http://127.0.0.1:8080/crm/",
  4. socket: "ws://localhost:8080/",
  5. //把登陆的用户名存入h5的缓存
  6. setUserInfo: function(username, token, uid) {
  7.       window.localStorage.setItem("username", username);
  8.       window.localStorage.setItem("token", token);
  9.       window.localStorage.setItem("uid", uid);
  10. },
  11. setPer: function(plist) { //设置权限列表
  12.       window.localStorage.setItem("plist", plist);
  13. },
  14. hasPer: function(pvalue) {
  15.       return window.localStorage.getItem("plist").includes(pvalue);
  16. },
  17. //从H5缓存中取出当前登录的用户名
  18. getUserName: function() {
  19.       return window.localStorage.getItem("username");
  20. },
  21. getToken: function() {
  22.       return window.localStorage.getItem("token");
  23. },
  24. getPer: function() {
  25.       return window.localStorage.getItem("plist");
  26. },
  27. getUid: function() {
  28.       return window.localStorage.getItem("uid");
  29. },
  30. //退出登录
  31. loginOut: function() {
  32.       globalData.setUserInfo(null, null, null);
  33.       window.location.href = "login.html";
  34. }
  35. };
  36. var a = globalData.getToken();
  37. if(a == null || a == "null") {
  38. var url = window.location.href;
  39. if(url.indexOf("login.html") >= 0) {
  40.  
  41. } else {
  42.       window.location.href = "login.html";
  43. }
  44. } else {
  45. var url = window.location.href;
  46. if(url.indexOf("login.html") >= 0) {
  47.       window.location.href = "index.html";
  48. }
  49. }
  50.  

6页面js、html

 

登录页面

登录成功

文章来源:https://blog.csdn.net/zjz_i/article/details/116107655

后台-系统设置-扩展变量-手机广告位-内容正文底部
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。
本文地址:https://jcdi.cn/diannaochangshi/fwq1/703.html

留言与评论(共有 0 条评论)
   
验证码:
后台-系统设置-扩展变量-手机广告位-评论底部广告位

教程弟

https://www.jcdi.cn/

统计代码 | 京ICP1234567-2号

Powered By 教程弟 教程弟

使用手机软件扫描微信二维码