spring boot+spring security集成以及Druid数据库连接池的问题
贴工程目录,其中bll目录下是service+dao层,common是一些公用的模块及功能类,web是controller层
用到了druid及Redis,工具及配置类目录(本文不介绍如何配置druid及Redis,但是我会把源文件放上)
web文件目录结构
接下来,说下大体的学习研究思路,在这块我是分了三部分来做验证的,这三部分只有securityconfig配置类有所区别
第一部分就是前后端不分离的security认证;
第二部是前后端分离,使用security+JWT认证;
第三部分是一个项目中既包含前段的web验证,也包含API的jwt认证;
一、第一部分的验证:
pom文件
<!-- security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- jwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</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()
spring boot+spring security集成以及Druid数据库连接池的问题的更多相关文章
- Spring Boot (四): Druid 连接池密码加密与监控
在上一篇文章<Spring Boot (三): ORM 框架 JPA 与连接池 Hikari> 我们介绍了 JPA 与连接池 Hikari 的整合使用,在国内使用比较多的连接池还有一个是阿 ...
- Spring Boot集成Druid数据库连接池
1. 前言 Druid数据库连接池由阿里巴巴开源,号称是java语言中最好的数据库连接池,是为监控而生的.Druid的官方地址是:https://github.com/alibaba/druid 通过 ...
- Spring Boot [使用 Druid 数据库连接池]
导读 最近一段时间比较忙,以至于很久没有更新Spring Boot系列文章,恰好最近用到Druid, 就将Spring Boot 使用 Druid作为数据源做一个简单的介绍. Druid介绍: Dru ...
- Spring Boot + Spring Cloud 实现权限管理系统 后端篇(七):集成 Druid 数据源
数据库连接池负责分配.管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个:释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏 ...
- spring boot rest 接口集成 spring security(2) - JWT配置
Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...
- spring boot rest 接口集成 spring security(1) - 最简配置
Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...
- 【spring boot】15.spring boot项目 采用Druid数据库连接池,并启用druid监控功能
在http://www.cnblogs.com/sxdcgaq8080/p/9039442.html的基础上,来看看spring boot项目中采用Druid连接池. GitHub地址:示例代码 == ...
- 14、Spring Boot 2.x 集成 Druid 数据源
14.Spring Boot 2.x 集成 Druid 数据源 完整源码: Spring-Boot-Demos
- spring boot:配置druid数据库连接池(开启sql防火墙/使用log4j2做异步日志/spring boot 2.3.2)
一,druid数据库连接池的功能? 1,Druid是阿里巴巴开发的号称为监控而生的数据库连接池 它的优点包括: 可以监控数据库访问性能 SQL执行日志 SQL防火墙 2,druid的官方站: http ...
随机推荐
- golang实现 快速排序算法
快速排序算法原理: b站https://b23.tv/uJqRYN package main import "fmt" //[]int{1,2,3,4,5,6,7,8} func ...
- angular中a标签带请求头下载excel
<!DOCTYPE html> <html lang="en" ng-app="app"> <head> <meta ...
- Salesforce学习笔记之吐槽
迄今感到的几个不方便 1. SOQL里没有SELECT * ,只好根据参考手册和用vs code的一个插件Schema Explorer来辅助生成SELECT语句. 2. SOQL不支持注释,Deve ...
- 关于Exceptionless日志收集框架会被Fiddler抓包,从而获取到ApiKey的问题
关于Exceptionless日志收集框架会被Fiddler抓包,从而获取到ApiKey的问题 环境:Exceptionless5.0.0.Linux.WPF客户端.Fiddler 问题:在使用Exc ...
- ES6中的变量的解构赋值, 解放我们的双手,实现变量的批量赋值
ES6--变量的解构赋值 引言 正文 一.数组的解构赋值 解构失败 不完全解构 默认值 二.对象的解构赋值 三.字符串的解构赋值 结束语 引言 变量的解构赋值, 听起来很复杂, 简单点说可以理解成批量 ...
- Linux 查网关和dns命令
一,查看网关(缺省路由)方法: 1.route -n 或netstat -rn2.ip route show 二, 查看DNS: nslookup www.baidu.com
- Cinder Volume 服务启动流程分析和周期性任务分析
1.cinder-volume服务的程序入口 #!/usr/bin/python2 # PBR Generated from u'console_scripts' import sys from ci ...
- 如何下载gitbub中的单个文件
1.进入Github文件夹,打开对应文件: 2.右键单击Raw,然后目标另存为即可.
- HM16.0之PCM模式——xCheckIntraPCM
参考:https://blog.csdn.net/cxy19931018/article/details/79781042 1.源代码: /** Check R-D costs for a CU wi ...
- pandas - 异常值处理
异常值概念:是指那些远离正常值的观测,即“不合群”观测.异常值的出现一般是人为的记录错误或者是设备的故障等,异常值的出现会对模型的创建和预测产生 严重的后果.当然异常值也不一定是坏事,有些情况下,通过 ...