贴工程目录,其中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数据库连接池的问题的更多相关文章

  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#开发笔记之03-为什么选择IsNotXXX方法而不是IsXXX方法?

    C#开发笔记概述 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/959 访问. 为什么有时候要选择IsNotXXX方法而 ...

  2. C#LeetCode刷题之#520-检测大写字母(Detect Capital)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3947 访问. 给定一个单词,你需要判断单词的大写使用是否正确. ...

  3. C#LeetCode刷题之#349-两个数组的交集(Intersection of Two Arrays)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4042 访问. 给定两个数组,编写一个函数来计算它们的交集. 输入 ...

  4. JavaScript call的示例

    作用: 改变函数执行时的作用域 let name = 'global name' function say(){ console.info(arguments) // 调用时接收的参数个数 conso ...

  5. C++ Templates 目录

    第1部分 : 基本概念 第1章 函数模板 1.1 初识函数模板 1.1.1 定义模板 1.1.2 使用模板 1.1.3 二阶段翻译 1.2 模板参数推导 1.3 多模板参数 1.3.1 返回类型的模板 ...

  6. Mockito鸡尾酒第一杯 单测Mock

    鸡尾酒 Mockito是Java的单元测试Mock框架. 它的logo是一杯古巴最著名的鸡尾酒Mojito, Mojito鸡尾酒,源自古巴的哈瓦那,带有浓厚的加勒比海风情. 并不浓烈,但是喝一杯下去, ...

  7. CentOS 安装、配置Nginx反向代理

    安装: yum install epel-release yum install nginx 配置: [root@bogon ~]# vim /etc/nginx/conf.d/default.con ...

  8. pytest的fixture怎么用?

    文章总览图 fixture和unittest是冲突的.舍弃unittest只用pytest. 会遇到在很多用例当中,它的前置条件是长得一样的.用例写的越来越多的时候,肯定会遇到前置条件都差不多,大家差 ...

  9. Docker 安装及配置镜像加速

    Docker 版本 随着 Docker 的飞速发展,企业级功能的上线,更好的服务意味着需要支付一定的费用,目前 Docker 被分为两个版本: community-edition 社区版 enterp ...

  10. 微信支付宝个人免签约即时到帐接口开发附demo

    支付界面: 扫码支付界面: 付成功后可以跳转到你程序指定的地址! demo: http://likeyunba.com/WeChat-Pay/