贴工程目录,其中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>

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

  1. # JWT
  2. jwt.secret=secret
  3. ## 过期时间 毫秒
  4. jwt.expiration=7200000
  5. ## 请求头
  6. jwt.token_header=Authorization
  7. ## token 前缀
  8. jwt.token_prefix=Bearer

spring security configuration配置类

  1. package com.ek.security.config;
  2.  
  3. import com.ek.security.EkUserDetailsService;
  4. import com.ek.security.handler.EkAuthenticationEntryPoint;
  5. import com.ek.security.handler.EkAuthenticationFailureHandler;
  6. import com.ek.security.handler.EkAuthenticationSuccessHandler;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.context.annotation.Configuration;
  9. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  10. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  11. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  12. import org.springframework.security.crypto.password.PasswordEncoder;
  13. import org.springframework.security.web.util.matcher.RequestMatcher;
  14.  
  15. import javax.servlet.http.HttpServletRequest;
  16. /**
  17. * @ClassName: EkWebSecurityConfig
  18. * @Description: 前后端不分离的security安全认证
  19. * @Author: edi_kai
  20. * @Version: V2.0
  21. **/
  22. @Configuration
  23. public class EkWebSecurityConfig extends WebSecurityConfigurerAdapter {
  24. @Autowired
  25. private EkUserDetailsService userDetailsService;
  26. @Autowired
  27. private EkAuthenticationEntryPoint authenticationEntryPoint;
  28. @Autowired
  29. private EkAuthenticationFailureHandler authenticationFailureHandler;
  30. @Autowired
  31. private EkAuthenticationSuccessHandler authenticationSuccessHandler;
  32. @Autowired
  33. PasswordEncoder passwordEncoder;
  34.  
  35. @Override
  36. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  37. // 添加自定义认证
  38. auth
  39. .userDetailsService(userDetailsService)
  40. .passwordEncoder(passwordEncoder)
  41. ;
  42. }
  43. @Override
  44. protected void configure(HttpSecurity http) throws Exception {
  45. // http.authorizeRequests().antMatchers("/**").permitAll();
  46. http.csrf().disable() //此处必须设置csrf disable,原因还不知道,对CSRF不太了解,后续我会查一下资料,然后在补充说明
  47. // .and()
  48. .httpBasic().authenticationEntryPoint(authenticationEntryPoint) // 没有凭证的操作,该部分不需要,可以不添加
  49. .and()
  50. .authorizeRequests()
  51. .antMatchers("/", "/index", "/toLogin", "/fail", "/druid/**").permitAll() //需要忽略的请求链接
  52. .anyRequest().authenticated()
  53. // .access("@rbacauthorityservice.hasPermission(request,authentication)") // RBAC 动态 url 认证
  54. .and()
  55. .formLogin().loginPage("/index") //指定自己的登录页面
  56. .loginProcessingUrl("/toLogin") // 登录action
  57. .usernameParameter("logName") // 登录用户名
  58. .passwordParameter("password") //密码
  59. .defaultSuccessUrl("/success", false) //设置登陆成功后跳转的页面
  60. .failureHandler(authenticationFailureHandler) //登录失败拦截器,也可以配置到指定的失败页面,我没写
  61. // .successHandler(authenticationSuccessHandler)
  62. .and()
  63. .logout()
  64. ;
  65. }
  66. }

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

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

  1. private String loginName;
  2. private String password;
  3. private String userName;
  4. private String userId;
  5. private Set<? extends GrantedAuthority> authorities; // 权限

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

  1. package com.ek.security;
  2.  
  3. import com.ek.bean.base.EkUser;
  4. import com.ek.service.base.IEkUserService;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.security.core.userdetails.UserDetails;
  9. import org.springframework.security.core.userdetails.UserDetailsService;
  10. import org.springframework.security.core.userdetails.UsernameNotFoundException;
  11. import org.springframework.stereotype.Component;
  12.  
  13. /**
  14. * @ClassName: EkUserDetailsService
  15. * @Description: TODO
  16. * @Author: edi_kai
  17. * @Date: 2019-08-06
  18. * @Version: V2.0
  19. **/
  20.  
  21. @Component
  22. public class EkUserDetailsService implements UserDetailsService {
  23. private Logger log = LoggerFactory.getLogger(this.getClass());
  24. @Autowired
  25. private IEkUserService userService;
  26. @Override
  27. public UserDetails loadUserByUsername(String loginName) throws UsernameNotFoundException {
  28. EkUserDetails userDetails = null;
  29. EkUser dbUser = userService.selectByLogName(loginName);
  30. if (null != dbUser){
  31. userDetails = new EkUserDetails();
  32. userDetails.setLoginName(dbUser.getLogName());
  33. userDetails.setPassword(dbUser.getPassWord());
  34. userDetails.setUserName(dbUser.getUserName());
  35. }else {
  36. log.error("{} is not exist.", loginName);
  37. throw new UsernameNotFoundException(String.format("%s is not exist.", loginName));
  38. }
  39. return userDetails;
  40. }
  41. }

EkAuthenticationEntryPoint 未登录的配置类

  1. package com.ek.security.handler;
  2. import com.alibaba.fastjson.JSON;
  3. import com.ek.msg.JsonMsg;
  4. import org.springframework.security.core.AuthenticationException;
  5. import org.springframework.security.web.AuthenticationEntryPoint;
  6. import org.springframework.stereotype.Component;
  7. import javax.servlet.ServletException;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10. import java.io.IOException;
  11. /**
  12. * @ClassName: EkAuthenticationEntryPoint
  13. * @Description: TODO
  14. * @Author: edi_kai
  15. * @Date: 2019-08-06
  16. * @Version: V2.0
  17. **/
  18. @Component
  19. public class EkAuthenticationEntryPoint implements AuthenticationEntryPoint {
  20. @Override
  21. public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
  22. httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
  23. httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
  24. httpServletResponse.setHeader("Access-Control-Allow-Credentials","true");
  25. // 设定类容为json的格式
  26. httpServletResponse.setContentType("application/json;charset=UTF-8");
  27. JsonMsg jsonMsg = new JsonMsg();
  28. jsonMsg.setCode(402);
  29. jsonMsg.setMsg("未登录");
  30. httpServletResponse.getWriter().write(JSON.toJSONString(jsonMsg));
  31. httpServletResponse.sendError(402,"未登录");
  32. }
  33. }

EkAuthenticationFailureHandler 认证失败配置类

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

EkAuthenticationSuccessHandler 认证成功配置类

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

EkPasswordEncoder 密码加密配置类

  1. @Component
  2. public class EkPasswordEncoder implements PasswordEncoder {
  3. PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(14);
  4. @Override
  5. public String encode(CharSequence charSequence) {
  6. System.out.println(charSequence);
  7. System.out.println(passwordEncoder.encode(charSequence));
  8. return passwordEncoder.encode(charSequence);
  9. }
  10. @Override
  11. public boolean matches(CharSequence charSequence, String s) {
  12. System.out.println(String.format("charSequence=%s, s=%s", charSequence, s));
  13. System.out.println(String.format("passwordEncoder.matches=%s", passwordEncoder.matches(charSequence, s)));
  14. return passwordEncoder.matches(charSequence, s);
  15. }
  16. }

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

二、JWT认证

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

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

  1. package com.ek.security.config;
  2.  
  3. import com.ek.security.EkUserDetailsService;
  4. import com.ek.security.handler.EkAuthenticationEntryPoint;
  5. import com.ek.security.handler.EkAuthenticationFailureHandler;
  6. import com.ek.security.handler.EkAuthenticationSuccessHandler;
  7. import com.ek.security.jwt.EkJwtAuthorizationTokenFilter;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.context.annotation.Bean;
  10. import org.springframework.context.annotation.Configuration;
  11. import org.springframework.security.authentication.AuthenticationManager;
  12. import org.springframework.security.config.BeanIds;
  13. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  14. import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
  15. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  16. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  17. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  18. import org.springframework.security.config.http.SessionCreationPolicy;
  19. import org.springframework.security.crypto.password.PasswordEncoder;
  20. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  21.  
  22. /**
  23. * @ClassName: EkWebSecurityConfig
  24. * @Description: 前后端分离,后端security安全认证
  25. * @Author: edi_kai
  26. * @Date: 2019-08-06
  27. * @Version: V2.0
  28. **/
  29.  
  30. //@Configuration
  31. //@EnableWebSecurity
  32. //@EnableGlobalMethodSecurity(prePostEnabled = true)
  33. public class EkApiSecurityConfig extends WebSecurityConfigurerAdapter {
  34. // @Autowired
  35. // private EkUserDetailsService userDetailsService;
  36. // @Autowired
  37. // private EkAuthenticationEntryPoint authenticationEntryPoint;
  38. // @Autowired
  39. // private EkAuthenticationFailureHandler authenticationFailureHandler;
  40. // @Autowired
  41. // private EkAuthenticationSuccessHandler authenticationSuccessHandler;
  42. // @Autowired
  43. // PasswordEncoder passwordEncoder;
  44. // @Autowired
  45. // EkJwtAuthorizationTokenFilter jwtAuthorizationTokenFilter;
  46. //
  47. // @Override
  48. // protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  49. // // 添加自定义认证
  50. // auth
  51. // .userDetailsService(userDetailsService)
  52. // .passwordEncoder(passwordEncoder)
  53. // ;
  54. // }
  55. // @Override
  56. // protected void configure(HttpSecurity http) throws Exception {
  57. //// http.authorizeRequests().antMatchers("/**").permitAll();
  58. // http.cors().and().csrf().disable()
  59. //// .and()
  60. // .httpBasic().authenticationEntryPoint(authenticationEntryPoint)
  61. // .and()
  62. // .authorizeRequests()
  63. // .antMatchers("/", "/index", "/toLogin", "/fail", "/druid/**").permitAll()
  64. // .anyRequest().authenticated()
  65. // // .access("@rbacauthorityservice.hasPermission(request,authentication)") // RBAC 动态 url 认证
  66. // .and()
  67. // .formLogin()//指定自己的登录页面
  68. // .failureHandler(authenticationFailureHandler)
  69. // .successHandler(authenticationSuccessHandler)
  70. // .and()
  71. // .logout()
  72. // .and()
  73. // .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
  74. // .and()
  75. // .addFilterBefore(jwtAuthorizationTokenFilter, UsernamePasswordAuthenticationFilter.class)
  76. // ;
  77. // }
  78. //
  79. // @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
  80. // @Override
  81. // public AuthenticationManager authenticationManagerBean() throws Exception {
  82. // return super.authenticationManagerBean();
  83. // }
  84. }

JWT配置类

  1. package com.ek.security.jwt;
  2.  
  3. import com.ek.security.EkUserDetails;
  4. import com.ek.util.redis.EkRedisUtil;
  5. import io.jsonwebtoken.Claims;
  6. import io.jsonwebtoken.Clock;
  7. import io.jsonwebtoken.Jwts;
  8. import io.jsonwebtoken.SignatureAlgorithm;
  9. import io.jsonwebtoken.impl.DefaultClock;
  10. import org.apache.commons.lang3.StringUtils;
  11. import org.slf4j.Logger;
  12. import org.slf4j.LoggerFactory;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.beans.factory.annotation.Value;
  15. import org.springframework.security.core.userdetails.UserDetails;
  16. import org.springframework.stereotype.Component;
  17.  
  18. import java.io.Serializable;
  19. import java.util.Date;
  20. import java.util.HashMap;
  21. import java.util.Map;
  22. import java.util.function.Function;
  23.  
  24. /**
  25. * @ClassName: EkJwtTokenUtil
  26. * @Description: JWT工具类,配合Redis
  27. * @Author: qin_hqing
  28. * @Date: 2019-08-07
  29. * @Version: V2.0
  30. **/
  31. @Component
  32. public class EkJwtTokenUtil implements Serializable {
  33.  
  34. private Logger log = LoggerFactory.getLogger(this.getClass());
  35.  
  36. private static final long serialVersionUID = -3301605591108950415L;
  37. // 权限缓存前缀
  38. private static final String REDIS_PREFIX_AUTH = "auth:";
  39. // 用户信息缓存前缀
  40. private static final String REDIS_PREFIX_USER = "user-details:";
  41.  
  42. @Autowired
  43. private EkRedisUtil redisUtil;
  44.  
  45. @Value("${jwt.secret}")
  46. private String secret;
  47.  
  48. @Value("${jwt.expiration}")
  49. private Long expiration;
  50.  
  51. @Value("${jwt.token_header}")
  52. private String tokenHeader;
  53.  
  54. private Clock clock = DefaultClock.INSTANCE;
  55.  
  56. /**
  57. * 生成token
  58. * @param userDetails
  59. * @return
  60. */
  61. public String generateToken(UserDetails userDetails) {
  62. EkUserDetails ekUserDetails = (EkUserDetails) userDetails;
  63. Map<String, Object> claims = new HashMap<>();
  64. String token = doGenerateToken(claims, ekUserDetails.getLoginName());
  65. String key = String.format("%s%s", REDIS_PREFIX_AUTH, ekUserDetails.getLoginName());
  66. redisUtil.set(key, token, expiration);
  67. return token;
  68. }
  69.  
  70. private String doGenerateToken(Map<String, Object> claims, String subject) {
  71. final Date createdDate = clock.now();
  72. final Date expirationDate = calculateExpirationDate(createdDate);
  73.  
  74. return Jwts.builder()
  75. .setClaims(claims)
  76. .setSubject(subject)
  77. .setIssuedAt(createdDate)
  78. .setExpiration(expirationDate)
  79. .signWith(SignatureAlgorithm.HS512, secret)
  80. .compact();
  81. }
  82.  
  83. private Date calculateExpirationDate(Date createdDate) {
  84. return new Date(createdDate.getTime() + expiration);
  85. }
  86.  
  87. /**
  88. * 校验token是否合法
  89. * @param token
  90. * @return
  91. */
  92. public Boolean validateToken(String token) {
  93. final String logName = getUsernameFromToken(token);
  94.  
  95. return StringUtils.isNotEmpty(token)
  96. && !isTokenExpired(token);
  97.  
  98. }
  99.  
  100. /**
  101. * 校验token是否合法
  102. * @param token
  103. * @param userDetails
  104. * @return
  105. */
  106. public Boolean validateToken(String token, UserDetails userDetails) {
  107. EkUserDetails user = (EkUserDetails) userDetails;
  108. final String logName = getUsernameFromToken(token);
  109.  
  110. String key = String.format("%s%s", REDIS_PREFIX_AUTH, user.getLoginName());
  111. if (redisUtil.containsKey(key)){
  112. return StringUtils.isNotEmpty(token)
  113. && token.equals(redisUtil.get(key))
  114. && (logName.equals(user.getLoginName())
  115. && !isTokenExpired(token));
  116. }
  117.  
  118. return false;
  119. }
  120.  
  121. /**
  122. * 根据token获取登录用户名
  123. * @param token
  124. * @return
  125. */
  126. public String getUsernameFromToken(String token) {
  127. return getClaimFromToken(token, Claims::getSubject);
  128. }
  129.  
  130. public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
  131. final Claims claims = getAllClaimsFromToken(token);
  132. return claimsResolver.apply(claims);
  133. }
  134.  
  135. private Claims getAllClaimsFromToken(String token) {
  136. return Jwts.parser()
  137. .setSigningKey(secret)
  138. .parseClaimsJws(token)
  139. .getBody();
  140. }
  141.  
  142. private Boolean isTokenExpired(String token) {
  143. final Date expiration = getExpirationDateFromToken(token);
  144. return expiration.before(clock.now());
  145. }
  146.  
  147. public Date getExpirationDateFromToken(String token) {
  148. return getClaimFromToken(token, Claims::getExpiration);
  149. }
  150.  
  151. /**
  152. * 添加EkUserDetails缓存
  153. * @param userDetails
  154. */
  155. public void putUserDetails(UserDetails userDetails){
  156. EkUserDetails user = (EkUserDetails) userDetails;
  157. String key = String.format("%s%s", REDIS_PREFIX_USER, user.getLoginName());
  158. redisUtil.set(key, user, expiration);
  159. }
  160.  
  161. /**
  162. * 根据token获取EkUserDetails
  163. * @param token
  164. * @return
  165. */
  166. public UserDetails getUserDetails(String token){
  167. String logName = getUsernameFromToken(token);
  168. String key = String.format("%s%s", REDIS_PREFIX_USER, logName);
  169. if (redisUtil.containsKey(key)){
  170. return redisUtil.get(key, EkUserDetails.class);
  171. }
  172. return null;
  173. }
  174. }
  1. package com.ek.security.jwt;
  2.  
  3. import com.ek.bean.base.EkUser;
  4. import com.ek.security.EkUserDetails;
  5. import com.ek.service.base.IEkUserService;
  6. import org.apache.commons.lang3.StringUtils;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.beans.factory.annotation.Value;
  9. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  10. import org.springframework.security.core.context.SecurityContextHolder;
  11. import org.springframework.stereotype.Component;
  12. import org.springframework.web.filter.OncePerRequestFilter;
  13.  
  14. import javax.servlet.FilterChain;
  15. import javax.servlet.ServletException;
  16. import javax.servlet.http.HttpServletRequest;
  17. import javax.servlet.http.HttpServletResponse;
  18. import java.io.IOException;
  19.  
  20. /**
  21. * @ClassName: EkJwtAuthorizationTokenFilter
  22. * @Description: JWT拦截器,对token进行验证
  23. * @Author: qin_hqing
  24. * @Date: 2019-08-07
  25. * @Version: V2.0
  26. **/
  27. @Component
  28. public class EkJwtAuthorizationTokenFilter extends OncePerRequestFilter {
  29.  
  30. @Value("${jwt.token_header}")
  31. private String EK_TOKEN_HEADER;
  32. @Value("${jwt.token_prefix}")
  33. private String EK_TOKEN_PREFIX;
  34.  
  35. @Autowired
  36. private EkJwtTokenUtil jwtTokenUtil;
  37. @Autowired
  38. private IEkUserService userService;
  39.  
  40. @Override
  41. protected void doFilterInternal(
  42. HttpServletRequest httpServletRequest,
  43. HttpServletResponse httpServletResponse,
  44. FilterChain filterChain) throws ServletException, IOException {
  45.  
  46. String authHeader = httpServletRequest.getHeader(this.EK_TOKEN_HEADER);
  47. if (StringUtils.isNotEmpty(authHeader) && authHeader.startsWith(this.EK_TOKEN_PREFIX)){
  48. final String authToken = StringUtils.substring(authHeader, this.EK_TOKEN_PREFIX.length());
  49. String logName = StringUtils.isNoneEmpty(authToken) ? jwtTokenUtil.getUsernameFromToken(authToken) : null;
  50.  
  51. if (StringUtils.isNotEmpty(logName) && SecurityContextHolder.getContext().getAuthentication() == null){
  52. EkUser user = userService.selectByLogName(logName);
  53. EkUserDetails userDetails = new EkUserDetails();
  54. userDetails.setPassword(user.getPassWord());
  55. userDetails.setLoginName(user.getLogName());
  56. userDetails.setUserName(user.getUserName());
  57. userDetails.setUserId(StringUtils.join(user.getId()));
  58.  
  59. if (jwtTokenUtil.validateToken(authToken, userDetails)){
  60. UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
  61. userDetails,
  62. null,
  63. userDetails.getAuthorities()
  64. );
  65. SecurityContextHolder.getContext().setAuthentication(authentication);
  66. }
  67. }
  68. }
  69. filterChain.doFilter(httpServletRequest, httpServletResponse);
  70. }
  71. }

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

  1. package com.ek.security.config;
  2.  
  3. import com.ek.security.EkUserDetailsService;
  4. import com.ek.security.handler.EkAuthenticationEntryPoint;
  5. import com.ek.security.handler.EkAuthenticationFailureHandler;
  6. import com.ek.security.handler.EkAuthenticationSuccessHandler;
  7. import com.ek.security.handler.EkPasswordEncoder;
  8. import com.ek.security.jwt.EkJwtAuthorizationTokenFilter;
  9. import com.ek.security.jwt.EkJwtTokenUtil;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.context.annotation.Bean;
  12. import org.springframework.context.annotation.Configuration;
  13. import org.springframework.core.annotation.Order;
  14. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  15. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  16. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  17. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  18. import org.springframework.security.config.http.SessionCreationPolicy;
  19. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  20. import org.springframework.security.crypto.password.PasswordEncoder;
  21. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  22.  
  23. @EnableWebSecurity
  24. public class EkMultiSecurityConfig {
  25. @Autowired
  26. private EkUserDetailsService userDetailsService;
  27. @Autowired
  28. private EkAuthenticationEntryPoint authenticationEntryPoint;
  29. @Autowired
  30. private EkAuthenticationFailureHandler authenticationFailureHandler;
  31. @Autowired
  32. private EkAuthenticationSuccessHandler authenticationSuccessHandler;
  33. @Autowired
  34. private EkPasswordEncoder passwordEncoder;
  35.  
  36. @Configuration
  37. @Order(1)
  38. public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {
  39.  
  40. @Autowired
  41. private EkJwtAuthorizationTokenFilter jwtAuthorizationTokenFilter;
  42.  
  43. @Override
  44. protected void configure(HttpSecurity http) throws Exception {
  45. http.antMatcher("/api/**") //<= Security only available for /api/**
  46. .authorizeRequests()
  47. .antMatchers("/api/register").permitAll()
  48. .antMatchers("/api/login").permitAll()
  49. .antMatchers("/api/public").permitAll()
  50. .antMatchers("/api/lost").permitAll()
  51. .anyRequest().authenticated()
  52. .and()
  53. .formLogin()
  54. .failureHandler(authenticationFailureHandler)
  55. .and()
  56. .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
  57. .and()
  58. .addFilterBefore(jwtAuthorizationTokenFilter, UsernamePasswordAuthenticationFilter.class)
  59. ;
  60. }
  61. }
  62.  
  63. @Configuration
  64. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  65. @Override
  66. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  67. // 添加自定义认证
  68. auth
  69. .userDetailsService(userDetailsService)
  70. .passwordEncoder(passwordEncoder)
  71. ;
  72. }
  73. @Override
  74. protected void configure(HttpSecurity http) throws Exception {
  75. // http.authorizeRequests().antMatchers("/**").permitAll();
  76. http.csrf().disable()
  77. // .and()
  78. .httpBasic().authenticationEntryPoint(authenticationEntryPoint)
  79. .and()
  80. .authorizeRequests()
  81. .antMatchers("/", "/index", "/toLogin", "/fail", "/druid/**").permitAll()
  82. .antMatchers("/resources/**").permitAll()
  83. .anyRequest().authenticated()
  84. // .access("@rbacauthorityservice.hasPermission(request,authentication)") // RBAC 动态 url 认证
  85. .and()
  86. .formLogin().loginPage("/index") //指定自己的登录页面
  87. .loginProcessingUrl("/toLogin")
  88. .usernameParameter("logName")
  89. .passwordParameter("password")
  90. .defaultSuccessUrl("/success", false)
  91. .failureHandler(authenticationFailureHandler)
  92. // .successHandler(authenticationSuccessHandler)
  93. .and()
  94. .logout()
  95. ;
  96. }
  97. }
  98. }

用到的其他类

  1. @RestController
  2. @RequestMapping("/users")
  3. public class EkUserController {
  4. private Logger log = LoggerFactory.getLogger(this.getClass());
  5. @Autowired
  6. private IEkUserService ekUserService;
  7. @RequestMapping(value = "", method = RequestMethod.GET)
  8. public JsonMsg getEkUserList(){
  9. log.info("--------------------列表--------------------------------");
  10. JsonMsg jsonMsg = new JsonMsg();
  11. List<EkUser> list = ekUserService.selectUserList(new HashMap<>());
  12. jsonMsg.setCode(200);
  13. jsonMsg.setMsg("success");
  14. jsonMsg.setData(list);
  15. return jsonMsg;
  16. }
  17. }
  1. @RestController
  2. public class LoginController {
  3. private Logger log = LoggerFactory.getLogger(this.getClass());
  4. @Autowired
  5. private IEkUserService ekUserService;
  6. @RequestMapping(value = {"", "/index"})
  7. public ModelAndView index(){
  8. log.info("--------------------首页--------------------------------");
  9. return new ModelAndView("index");
  10. }
  11. @RequestMapping(value = "/fail")
  12. public ModelAndView fail(){
  13. log.info("--------------------fail--------------------------------");
  14. return new ModelAndView("fail");
  15. }
  16. @RequestMapping(value = "/toLogin", method = RequestMethod.POST)
  17. public ModelAndView toLogin(){
  18. log.info("--------------------toLogin--------------------------------");
  19. return new ModelAndView("success");
  20. }
  21.  
  22. @RequestMapping(value = "/success")
  23. public ModelAndView success(){
  24. log.info("--------------------success--------------------------------");
  25. return new ModelAndView("success");
  26. }
  27. }

说明:

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

  1. .antMatchers("/", "/index", "/toLogin", "/fail", "/druid/**").permitAll()

spring boot+spring security集成以及Druid数据库连接池的问题的更多相关文章

  1. Spring Boot (四): Druid 连接池密码加密与监控

    在上一篇文章<Spring Boot (三): ORM 框架 JPA 与连接池 Hikari> 我们介绍了 JPA 与连接池 Hikari 的整合使用,在国内使用比较多的连接池还有一个是阿 ...

  2. Spring Boot集成Druid数据库连接池

    1. 前言 Druid数据库连接池由阿里巴巴开源,号称是java语言中最好的数据库连接池,是为监控而生的.Druid的官方地址是:https://github.com/alibaba/druid 通过 ...

  3. Spring Boot [使用 Druid 数据库连接池]

    导读 最近一段时间比较忙,以至于很久没有更新Spring Boot系列文章,恰好最近用到Druid, 就将Spring Boot 使用 Druid作为数据源做一个简单的介绍. Druid介绍: Dru ...

  4. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(七):集成 Druid 数据源

    数据库连接池负责分配.管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个:释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏 ...

  5. spring boot rest 接口集成 spring security(2) - JWT配置

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  6. spring boot rest 接口集成 spring security(1) - 最简配置

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  7. 【spring boot】15.spring boot项目 采用Druid数据库连接池,并启用druid监控功能

    在http://www.cnblogs.com/sxdcgaq8080/p/9039442.html的基础上,来看看spring boot项目中采用Druid连接池. GitHub地址:示例代码 == ...

  8. 14、Spring Boot 2.x 集成 Druid 数据源

    14.Spring Boot 2.x 集成 Druid 数据源 完整源码: Spring-Boot-Demos

  9. spring boot:配置druid数据库连接池(开启sql防火墙/使用log4j2做异步日志/spring boot 2.3.2)

    一,druid数据库连接池的功能? 1,Druid是阿里巴巴开发的号称为监控而生的数据库连接池 它的优点包括: 可以监控数据库访问性能 SQL执行日志 SQL防火墙 2,druid的官方站: http ...

随机推荐

  1. C# 8.0 的新特性概览和讲解

    本文转自 https://blog.csdn.net/hez2010/article/details/84036742 C# 8.0 的新特性概览和讲解 前言 新的改变 可空引用类型(Nullable ...

  2. Docker服务开放了这个端口,服务器分分钟变肉机

    之前有很多朋友提过,当使用docker-maven-plugin打包SpringBoot应用的Docker镜像时,服务器需要开放2375端口.由于开放了端口没有做任何安全保护,会引起安全漏洞,被人入侵 ...

  3. Java字符串中有多少个字符多少个char、字节

    Java 中Char是两个字节,Char在Java中也被称为代码单元(Code Unit) . Java中的字符与代码点(Code Unit)一 一对应,而可能对应一个或者两个 代码单元 字符串的le ...

  4. Spring Security 实战干货:实现自定义退出登录

    文章目录 1. 前言 2. 我们使用 Spring Security 登录后都做了什么 2. 退出登录需要我们做什么 3. Spring Security 中的退出登录 3.1 LogoutFilte ...

  5. getAnnotation的一个坑

    // TableField annotation = f.getAnnotation(TableField.class); // 不建议使用这个,建议使用下面这个方法获取 TableField ann ...

  6. linux云服务器搭建 express后台 nginx转发

    购买云服务器 或者自己在本地搭建一个虚拟机 (我用的是腾讯云云服务器(CVM),或者可以购买阿里云 ecs服务器) 购买完成后 配置安全组 允许http https ftp 端口 一般运营商会提供说明 ...

  7. CSS动画实例:行星和卫星

    设页面中有<div class=" planet "></div>,用来绘制一个行星和卫星图形.这个图形包括三部分:行星.卫星和卫星旋转的轨道.定义. pl ...

  8. Java数据结构——二叉树的遍历(汇总)

    二叉树的遍历分为深度优先遍历(DFS)和广度优先遍历(BFS) DFS遍历主要有: 前序遍历 中序遍历 后序遍历 一.递归实现DFSNode.java: public class Node { pri ...

  9. MySQL添加外键报错 - referencing column 'xx' and referenced column 'xx' in foreign key constraint 'xx' are incompatible

    MySQL给两个表添加外键时,报错 翻译意思是:外键约束“xx”中的引用列“xx”和引用列“xx”不兼容 说明两个表关联的列数据类型不一致,比如:varchar 与 int,或者 int无符号 与 i ...

  10. 想学习SEO可以看哪些书籍

    http://www.wocaoseo.com/thread-28-1-1.html 除了一些常见的比如入门推荐<走进搜索引擎>和进阶推荐<这就是搜索引擎--核心技术详解>之外 ...