• spring boot+spring security集成以及Druid数据库连接池的问题


     贴工程目录,其中bll目录下是service+dao层,common是一些公用的模块及功能类,web是controller层

    用到了druid及Redis,工具及配置类目录(本文不介绍如何配置druid及Redis,但是我会把源文件放上)

    web文件目录结构

    接下来,说下大体的学习研究思路,在这块我是分了三部分来做验证的,这三部分只有securityconfig配置类有所区别

      第一部分就是前后端不分离的security认证;

      第二部是前后端分离,使用security+JWT认证;

      第三部分是一个项目中既包含前段的web验证,也包含API的jwt认证;

    一、第一部分的验证:

    pom文件

     1        <!-- security -->
     2         <dependency>
     3             <groupId>org.springframework.boot</groupId>
     4             <artifactId>spring-boot-starter-security</artifactId>
     5         </dependency>
     6         <!-- jwt -->
     7         <dependency>
     8             <groupId>io.jsonwebtoken</groupId>
     9             <artifactId>jjwt</artifactId>
    10             <version>0.9.0</version>
    11         </dependency>    

    配置类中会用到的常量参数

    # JWT
    jwt.secret=secret
    ## 过期时间 毫秒
    jwt.expiration=7200000
    ## 请求头
    jwt.token_header=Authorization
    ## token 前缀
    jwt.token_prefix=Bearer 

    spring security configuration配置类

    package com.ek.security.config;
    
    import com.ek.security.EkUserDetailsService;
    import com.ek.security.handler.EkAuthenticationEntryPoint;
    import com.ek.security.handler.EkAuthenticationFailureHandler;
    import com.ek.security.handler.EkAuthenticationSuccessHandler;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.web.util.matcher.RequestMatcher;
    
    import javax.servlet.http.HttpServletRequest;
    /**
     * @ClassName: EkWebSecurityConfig
     * @Description: 前后端不分离的security安全认证
     * @Author: edi_kai
     * @Version: V2.0
     **/
    @Configuration
    public class EkWebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        private EkUserDetailsService userDetailsService;
        @Autowired
        private EkAuthenticationEntryPoint authenticationEntryPoint;
        @Autowired
        private EkAuthenticationFailureHandler authenticationFailureHandler;
        @Autowired
        private EkAuthenticationSuccessHandler authenticationSuccessHandler;
        @Autowired
        PasswordEncoder passwordEncoder;
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            // 添加自定义认证
            auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder)
            ;
        }
        @Override
        protected void configure(HttpSecurity http) throws Exception {
    //        http.authorizeRequests().antMatchers("/**").permitAll();
            http.csrf().disable() //此处必须设置csrf disable,原因还不知道,对CSRF不太了解,后续我会查一下资料,然后在补充说明
    //            .and()
                    .httpBasic().authenticationEntryPoint(authenticationEntryPoint) // 没有凭证的操作,该部分不需要,可以不添加
                .and()
                    .authorizeRequests()
                    .antMatchers("/", "/index", "/toLogin", "/fail", "/druid/**").permitAll()  //需要忽略的请求链接
                    .anyRequest().authenticated()
        //            .access("@rbacauthorityservice.hasPermission(request,authentication)") // RBAC 动态 url 认证
                .and()
                    .formLogin().loginPage("/index") //指定自己的登录页面
                    .loginProcessingUrl("/toLogin") // 登录action
                    .usernameParameter("logName")  // 登录用户名
                    .passwordParameter("password")  //密码
                    .defaultSuccessUrl("/success", false) //设置登陆成功后跳转的页面
                    .failureHandler(authenticationFailureHandler) //登录失败拦截器,也可以配置到指定的失败页面,我没写
    //                .successHandler(authenticationSuccessHandler)
                .and()
                    .logout()
            ;
        }
    }

    接下来看下该配置类中用到的其他配置类

    EkUserDetails用户认证实体类,自己添加get/set方法,基本的Java类,不需要添加任何注解

    private String loginName;
    private String password;
    private String userName;
    private String userId;
    private Set<? extends GrantedAuthority> authorities; // 权限

    EkUserDetailsService登录认证,我这边没有配置权限,只是为了验证spring-security

    package com.ek.security;
    
    import com.ek.bean.base.EkUser;
    import com.ek.service.base.IEkUserService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.stereotype.Component;
    
    /**
     * @ClassName: EkUserDetailsService
     * @Description: TODO
     * @Author: edi_kai
     * @Date: 2019-08-06
     * @Version: V2.0
     **/
    
    @Component
    public class EkUserDetailsService implements UserDetailsService {
        private Logger log = LoggerFactory.getLogger(this.getClass());
        @Autowired
        private IEkUserService userService;
        @Override
        public UserDetails loadUserByUsername(String loginName) throws UsernameNotFoundException {
            EkUserDetails userDetails = null;
            EkUser dbUser = userService.selectByLogName(loginName);
            if (null != dbUser){
                userDetails = new EkUserDetails();
                userDetails.setLoginName(dbUser.getLogName());
                userDetails.setPassword(dbUser.getPassWord());
                userDetails.setUserName(dbUser.getUserName());
            }else {
                log.error("{} is not exist.", loginName);
                throw new UsernameNotFoundException(String.format("%s is not exist.", loginName));
            }
            return userDetails;
        }
    }

    EkAuthenticationEntryPoint 未登录的配置类

    package com.ek.security.handler;
    import com.alibaba.fastjson.JSON;
    import com.ek.msg.JsonMsg;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.AuthenticationEntryPoint;
    import org.springframework.stereotype.Component;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    /**
     * @ClassName: EkAuthenticationEntryPoint
     * @Description: TODO
     * @Author: edi_kai
     * @Date: 2019-08-06
     * @Version: V2.0
     **/
    @Component
    public class EkAuthenticationEntryPoint implements AuthenticationEntryPoint {
        @Override
        public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
            httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
            httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            httpServletResponse.setHeader("Access-Control-Allow-Credentials","true");
            // 设定类容为json的格式
            httpServletResponse.setContentType("application/json;charset=UTF-8");
            JsonMsg jsonMsg = new JsonMsg();
            jsonMsg.setCode(402);
            jsonMsg.setMsg("未登录");
            httpServletResponse.getWriter().write(JSON.toJSONString(jsonMsg));
            httpServletResponse.sendError(402,"未登录");
        }
    }

     EkAuthenticationFailureHandler 认证失败配置类

    @Component
    public class EkAuthenticationFailureHandler implements AuthenticationFailureHandler {
        @Override
        public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
            httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
            httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            httpServletResponse.setHeader("Access-Control-Allow-Credentials","true");
            // 设定类容为json的格式
            httpServletResponse.setContentType("application/json;charset=UTF-8");
            JsonMsg jsonMsg = new JsonMsg();
            jsonMsg.setCode(400);
            jsonMsg.setMsg("登录失败");
            httpServletResponse.getWriter().write(JSON.toJSONString(jsonMsg));
        }
    }

    EkAuthenticationSuccessHandler 认证成功配置类

    @Component
    public class EkAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
        @Override
        public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
            httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
            httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            httpServletResponse.setHeader("Access-Control-Allow-Credentials","true");
            // 设定类容为json的格式
            httpServletResponse.setContentType("application/json;charset=UTF-8");
            JsonMsg jsonMsg = new JsonMsg();
            jsonMsg.setCode(200);
            jsonMsg.setMsg("登录成功");
            httpServletResponse.getWriter().write(JSON.toJSONString(jsonMsg));
        }
    }

    EkPasswordEncoder 密码加密配置类

    @Component
    public class EkPasswordEncoder implements PasswordEncoder {
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(14);
        @Override
        public String encode(CharSequence charSequence) {
            System.out.println(charSequence);
            System.out.println(passwordEncoder.encode(charSequence));
            return passwordEncoder.encode(charSequence);
        }
        @Override
        public boolean matches(CharSequence charSequence, String s) {
            System.out.println(String.format("charSequence=%s, s=%s", charSequence, s));
            System.out.println(String.format("passwordEncoder.matches=%s", passwordEncoder.matches(charSequence, s)));
            return passwordEncoder.matches(charSequence, s);
        }
    }

    到这里配置就算完成了,启动服务就可以看到效果了,没有登录的情况下访问permitAll()链接都会跳转到/index登录页,登录成功后再跳转。

    二、JWT认证

    我们只需要修改securityconfig配置类,并添加JWT配置即可其他不用修改

    修改后的security配置类,我重新定义了个类,把注释去掉即可

    package com.ek.security.config;
    
    import com.ek.security.EkUserDetailsService;
    import com.ek.security.handler.EkAuthenticationEntryPoint;
    import com.ek.security.handler.EkAuthenticationFailureHandler;
    import com.ek.security.handler.EkAuthenticationSuccessHandler;
    import com.ek.security.jwt.EkJwtAuthorizationTokenFilter;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.config.BeanIds;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.config.http.SessionCreationPolicy;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    
    /**
     * @ClassName: EkWebSecurityConfig
     * @Description: 前后端分离,后端security安全认证
     * @Author: edi_kai
     * @Date: 2019-08-06
     * @Version: V2.0
     **/
    
    //@Configuration
    //@EnableWebSecurity
    //@EnableGlobalMethodSecurity(prePostEnabled = true)
    public class EkApiSecurityConfig extends WebSecurityConfigurerAdapter {
    //    @Autowired
    //    private EkUserDetailsService userDetailsService;
    //    @Autowired
    //    private EkAuthenticationEntryPoint authenticationEntryPoint;
    //    @Autowired
    //    private EkAuthenticationFailureHandler authenticationFailureHandler;
    //    @Autowired
    //    private EkAuthenticationSuccessHandler authenticationSuccessHandler;
    //    @Autowired
    //    PasswordEncoder passwordEncoder;
    //    @Autowired
    //    EkJwtAuthorizationTokenFilter jwtAuthorizationTokenFilter;
    //
    //    @Override
    //    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    //        // 添加自定义认证
    //        auth
    //            .userDetailsService(userDetailsService)
    //            .passwordEncoder(passwordEncoder)
    //        ;
    //    }
    //    @Override
    //    protected void configure(HttpSecurity http) throws Exception {
    ////        http.authorizeRequests().antMatchers("/**").permitAll();
    //        http.cors().and().csrf().disable()
    ////            .and()
    //                .httpBasic().authenticationEntryPoint(authenticationEntryPoint)
    //            .and()
    //                .authorizeRequests()
    //                .antMatchers("/", "/index", "/toLogin", "/fail", "/druid/**").permitAll()
    //                .anyRequest().authenticated()
    //    //            .access("@rbacauthorityservice.hasPermission(request,authentication)") // RBAC 动态 url 认证
    //            .and()
    //                .formLogin()//指定自己的登录页面
    //                .failureHandler(authenticationFailureHandler)
    //                .successHandler(authenticationSuccessHandler)
    //            .and()
    //                .logout()
    //            .and()
    //                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    //            .and()
    //                .addFilterBefore(jwtAuthorizationTokenFilter, UsernamePasswordAuthenticationFilter.class)
    //        ;
    //    }
    //
    //    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    //    @Override
    //    public AuthenticationManager authenticationManagerBean() throws Exception {
    //        return super.authenticationManagerBean();
    //    }
    }

    JWT配置类

    package com.ek.security.jwt;
    
    import com.ek.security.EkUserDetails;
    import com.ek.util.redis.EkRedisUtil;
    import io.jsonwebtoken.Claims;
    import io.jsonwebtoken.Clock;
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    import io.jsonwebtoken.impl.DefaultClock;
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.stereotype.Component;
    
    import java.io.Serializable;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.function.Function;
    
    /**
     * @ClassName: EkJwtTokenUtil
     * @Description: JWT工具类,配合Redis
     * @Author: qin_hqing
     * @Date: 2019-08-07
     * @Version: V2.0
     **/
    @Component
    public class EkJwtTokenUtil implements Serializable {
    
        private Logger log = LoggerFactory.getLogger(this.getClass());
    
        private static final long serialVersionUID = -3301605591108950415L;
        // 权限缓存前缀
        private static final String REDIS_PREFIX_AUTH = "auth:";
        // 用户信息缓存前缀
        private static final String REDIS_PREFIX_USER = "user-details:";
    
        @Autowired
        private EkRedisUtil redisUtil;
    
        @Value("${jwt.secret}")
        private String secret;
    
        @Value("${jwt.expiration}")
        private Long expiration;
    
        @Value("${jwt.token_header}")
        private String tokenHeader;
    
        private Clock clock = DefaultClock.INSTANCE;
    
        /**
         * 生成token
         * @param userDetails
         * @return
         */
        public String generateToken(UserDetails userDetails) {
            EkUserDetails ekUserDetails = (EkUserDetails) userDetails;
            Map<String, Object> claims = new HashMap<>();
            String token = doGenerateToken(claims, ekUserDetails.getLoginName());
            String key = String.format("%s%s", REDIS_PREFIX_AUTH, ekUserDetails.getLoginName());
            redisUtil.set(key, token, expiration);
            return token;
        }
    
        private String doGenerateToken(Map<String, Object> claims, String subject) {
            final Date createdDate = clock.now();
            final Date expirationDate = calculateExpirationDate(createdDate);
    
            return Jwts.builder()
                    .setClaims(claims)
                    .setSubject(subject)
                    .setIssuedAt(createdDate)
                    .setExpiration(expirationDate)
                    .signWith(SignatureAlgorithm.HS512, secret)
                    .compact();
        }
    
        private Date calculateExpirationDate(Date createdDate) {
            return new Date(createdDate.getTime() + expiration);
        }
    
        /**
         * 校验token是否合法
         * @param token
         * @return
         */
        public Boolean validateToken(String token) {
            final String logName = getUsernameFromToken(token);
    
            return StringUtils.isNotEmpty(token)
                    && !isTokenExpired(token);
    
        }
    
        /**
         * 校验token是否合法
         * @param token
         * @param userDetails
         * @return
         */
        public Boolean validateToken(String token, UserDetails userDetails) {
            EkUserDetails user = (EkUserDetails) userDetails;
            final String logName = getUsernameFromToken(token);
    
            String key = String.format("%s%s", REDIS_PREFIX_AUTH, user.getLoginName());
            if (redisUtil.containsKey(key)){
                return StringUtils.isNotEmpty(token)
                        && token.equals(redisUtil.get(key))
                        && (logName.equals(user.getLoginName())
                        && !isTokenExpired(token));
            }
    
            return false;
        }
    
        /**
         * 根据token获取登录用户名
         * @param token
         * @return
         */
        public String getUsernameFromToken(String token) {
            return getClaimFromToken(token, Claims::getSubject);
        }
    
        public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
            final Claims claims = getAllClaimsFromToken(token);
            return claimsResolver.apply(claims);
        }
    
        private Claims getAllClaimsFromToken(String token) {
            return Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
        }
    
        private Boolean isTokenExpired(String token) {
            final Date expiration = getExpirationDateFromToken(token);
            return expiration.before(clock.now());
        }
    
        public Date getExpirationDateFromToken(String token) {
            return getClaimFromToken(token, Claims::getExpiration);
        }
    
        /**
         * 添加EkUserDetails缓存
         * @param userDetails
         */
        public void putUserDetails(UserDetails userDetails){
            EkUserDetails user = (EkUserDetails) userDetails;
            String key = String.format("%s%s", REDIS_PREFIX_USER, user.getLoginName());
            redisUtil.set(key, user, expiration);
        }
    
        /**
         * 根据token获取EkUserDetails
         * @param token
         * @return
         */
        public UserDetails getUserDetails(String token){
            String logName = getUsernameFromToken(token);
            String key = String.format("%s%s", REDIS_PREFIX_USER, logName);
            if (redisUtil.containsKey(key)){
                return redisUtil.get(key, EkUserDetails.class);
            }
            return null;
        }
    }
    package com.ek.security.jwt;
    
    import com.ek.bean.base.EkUser;
    import com.ek.security.EkUserDetails;
    import com.ek.service.base.IEkUserService;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.stereotype.Component;
    import org.springframework.web.filter.OncePerRequestFilter;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * @ClassName: EkJwtAuthorizationTokenFilter
     * @Description: JWT拦截器,对token进行验证
     * @Author: qin_hqing
     * @Date: 2019-08-07
     * @Version: V2.0
     **/
    @Component
    public class EkJwtAuthorizationTokenFilter extends OncePerRequestFilter {
    
        @Value("${jwt.token_header}")
        private String EK_TOKEN_HEADER;
        @Value("${jwt.token_prefix}")
        private String EK_TOKEN_PREFIX;
    
        @Autowired
        private EkJwtTokenUtil jwtTokenUtil;
        @Autowired
        private IEkUserService userService;
    
        @Override
        protected void doFilterInternal(
                HttpServletRequest httpServletRequest,
                HttpServletResponse httpServletResponse,
                FilterChain filterChain) throws ServletException, IOException {
    
            String authHeader = httpServletRequest.getHeader(this.EK_TOKEN_HEADER);
            if (StringUtils.isNotEmpty(authHeader) && authHeader.startsWith(this.EK_TOKEN_PREFIX)){
                final String authToken = StringUtils.substring(authHeader, this.EK_TOKEN_PREFIX.length());
                String logName = StringUtils.isNoneEmpty(authToken) ? jwtTokenUtil.getUsernameFromToken(authToken) : null;
    
                if (StringUtils.isNotEmpty(logName) && SecurityContextHolder.getContext().getAuthentication() == null){
                    EkUser user = userService.selectByLogName(logName);
                    EkUserDetails userDetails = new EkUserDetails();
                    userDetails.setPassword(user.getPassWord());
                    userDetails.setLoginName(user.getLogName());
                    userDetails.setUserName(user.getUserName());
                    userDetails.setUserId(StringUtils.join(user.getId()));
    
                    if (jwtTokenUtil.validateToken(authToken, userDetails)){
                        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                                userDetails,
                                null,
                                userDetails.getAuthorities()
                        );
                        SecurityContextHolder.getContext().setAuthentication(authentication);
                    }
                }
            }
            filterChain.doFilter(httpServletRequest, httpServletResponse);
        }
    }

    三、在二的基础上只修改securityconfig配置类即可

    package com.ek.security.config;
    
    import com.ek.security.EkUserDetailsService;
    import com.ek.security.handler.EkAuthenticationEntryPoint;
    import com.ek.security.handler.EkAuthenticationFailureHandler;
    import com.ek.security.handler.EkAuthenticationSuccessHandler;
    import com.ek.security.handler.EkPasswordEncoder;
    import com.ek.security.jwt.EkJwtAuthorizationTokenFilter;
    import com.ek.security.jwt.EkJwtTokenUtil;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.annotation.Order;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.config.http.SessionCreationPolicy;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    
    @EnableWebSecurity
    public class EkMultiSecurityConfig {
        @Autowired
        private EkUserDetailsService userDetailsService;
        @Autowired
        private EkAuthenticationEntryPoint authenticationEntryPoint;
        @Autowired
        private EkAuthenticationFailureHandler authenticationFailureHandler;
        @Autowired
        private EkAuthenticationSuccessHandler authenticationSuccessHandler;
        @Autowired
        private EkPasswordEncoder passwordEncoder;
    
        @Configuration
        @Order(1)
        public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {
    
            @Autowired
            private EkJwtAuthorizationTokenFilter jwtAuthorizationTokenFilter;
    
            @Override
            protected void configure(HttpSecurity http) throws Exception {
                http.antMatcher("/api/**") //<= Security only available for /api/**
                        .authorizeRequests()
                        .antMatchers("/api/register").permitAll()
                        .antMatchers("/api/login").permitAll()
                        .antMatchers("/api/public").permitAll()
                        .antMatchers("/api/lost").permitAll()
                        .anyRequest().authenticated()
                    .and()
                        .formLogin()
                        .failureHandler(authenticationFailureHandler)
                    .and()
                        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                        .addFilterBefore(jwtAuthorizationTokenFilter, UsernamePasswordAuthenticationFilter.class)
                ;
            }
        }
    
        @Configuration
        public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
            @Override
            protected void configure(AuthenticationManagerBuilder auth) throws Exception {
                // 添加自定义认证
                auth
                        .userDetailsService(userDetailsService)
                        .passwordEncoder(passwordEncoder)
                ;
            }
            @Override
            protected void configure(HttpSecurity http) throws Exception {
                //        http.authorizeRequests().antMatchers("/**").permitAll();
                http.csrf().disable()
    //                .and()
                        .httpBasic().authenticationEntryPoint(authenticationEntryPoint)
                    .and()
                        .authorizeRequests()
                        .antMatchers("/", "/index", "/toLogin", "/fail", "/druid/**").permitAll()
                        .antMatchers("/resources/**").permitAll()
                        .anyRequest().authenticated()
                        //            .access("@rbacauthorityservice.hasPermission(request,authentication)") // RBAC 动态 url 认证
                    .and()
                        .formLogin().loginPage("/index") //指定自己的登录页面
                        .loginProcessingUrl("/toLogin")
                        .usernameParameter("logName")
                        .passwordParameter("password")
                        .defaultSuccessUrl("/success", false)
                        .failureHandler(authenticationFailureHandler)
    //                .successHandler(authenticationSuccessHandler)
                    .and()
                        .logout()
                ;
            }
        }
    }

    用到的其他类

    @RestController
    @RequestMapping("/users")
    public class EkUserController {
        private Logger log = LoggerFactory.getLogger(this.getClass());
        @Autowired
        private IEkUserService ekUserService;
        @RequestMapping(value = "", method = RequestMethod.GET)
        public JsonMsg getEkUserList(){
            log.info("--------------------列表--------------------------------");
            JsonMsg jsonMsg = new JsonMsg();
            List<EkUser> list = ekUserService.selectUserList(new HashMap<>());
            jsonMsg.setCode(200);
            jsonMsg.setMsg("success");
            jsonMsg.setData(list);
            return jsonMsg;
        }
    }
    @RestController
    public class LoginController {
        private Logger log = LoggerFactory.getLogger(this.getClass());
        @Autowired
        private IEkUserService ekUserService;
        @RequestMapping(value = {"", "/index"})
        public ModelAndView index(){
            log.info("--------------------首页--------------------------------");
            return new ModelAndView("index");
        }
        @RequestMapping(value = "/fail")
        public ModelAndView fail(){
            log.info("--------------------fail--------------------------------");
            return new ModelAndView("fail");
        }
        @RequestMapping(value = "/toLogin", method = RequestMethod.POST)
        public ModelAndView toLogin(){
            log.info("--------------------toLogin--------------------------------");
            return new ModelAndView("success");
        }
    
        @RequestMapping(value = "/success")
        public ModelAndView success(){
            log.info("--------------------success--------------------------------");
            return new ModelAndView("success");
        }
    }

    说明:

      关于druid监控登录的问题,我把它放到了下面这个地方,网上查资料说是添加http.csrf().ignoringAntMatchers("/druid/*")就行,但是我添加后并没有成功。

    .antMatchers("/", "/index", "/toLogin", "/fail", "/druid/**").permitAll()
  • 相关阅读:
    466 你真的了解回流和重绘吗
    465 从一道题浅说 JavaScript 的事件循环
    460 动态组件
    458 MongoDB安装
    457 vue d13
    450 for of 循环
    六种排序算法的Js实现
    你真的理解了比较运算符吗?
    5个有趣且不必要的 JavaScipt 技巧
    7个常见的 JavaScript 测验及解答
  • 原文地址:https://www.cnblogs.com/edi-kai/p/11316676.html
Copyright © 2020-2023  润新知