zoukankan      html  css  js  c++  java
  • 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()
  • 相关阅读:
    [saiku] 系统登录成功后查询Cubes
    216. Combination Sum III
    215. Kth Largest Element in an Array
    214. Shortest Palindrome
    213. House Robber II
    212. Word Search II
    211. Add and Search Word
    210. Course Schedule II
    分硬币问题
    开始学习Python
  • 原文地址:https://www.cnblogs.com/edi-kai/p/11316676.html
Copyright © 2011-2022 走看看