package com.example.service;
import com.example.pojo.User;
public interface UserService {
User getUserByUsername(String username);
}
package com.example.service.impl;
import com.example.mapper.UserMapper;
import com.example.pojo.User;
import com.example.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class UserServiceImpl implements UserService {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Resource
UserMapper userMapper;
@Override
public User getUserByUsername(String username) {
return userMapper.loadUserByUsername(username);
}
}
package com.example.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
@ApiModel("自定义响应实体类")
public class ResponseResult<T> implements Serializable {
@ApiModelProperty("响应码")
private Integer code;
@ApiModelProperty("响应消息")
private String message;
@ApiModelProperty("响应数据")
private T data;
public ResponseResult() {
super();
}
public ResponseResult(Integer code) {
this.code = code;
}
public ResponseResult(Integer code, String message) {
this.code = code;
this.message = message;
}
public ResponseResult(Integer code, T data) {
this.code = code;
this.data = data;
}
public ResponseResult(String message, T data) {
this.message = message;
this.data = data;
}
public ResponseResult(Integer code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "ResponseResult{" +
"code=" + code +
", message='" + message + '\'' +
", data=" + data +
'}';
}
}
package com.example.controller;
import com.example.pojo.User;
import com.example.service.UserService;
import com.example.vo.ResponseResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@Api(tags="登录控制器")
@Controller
public class LoginController {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Resource
// @Autowired
private UserService userService;
@RequestMapping(value = "/loginPage")
public String loginPage(Authentication auth) {
System.out.println("--------/login------------");
return "/loginPage";
}
// @RequestMapping(value = "/login")
// public String login() {
// System.out.println("--------/login-----books-------");
//// return "/index";
// return "/books";
// }
/**
* 登录成功处理
* @return 返回用户登录信息,包括权限角色
*/
@ApiOperation("登录成功处理,返回用户登录信息,包括权限角色")
@RequestMapping("/login/success")
// @ResponseBody
// public ResponseResult<User> loginSuccess() {
public String loginSuccess(Model model) {
String username = SecurityContextHolder.getContext().getAuthentication().getName();
logger.info("=====/login/success===loginSuccess========"+username);
User user = userService.getUserByUsername(username);
model.addAttribute("h1_text", "this is a index page!");
model.addAttribute("username", username);
model.addAttribute("user", user);
// return new ResponseResult<>("success",user);System.out.println("--------/login-----books-------");
return "/index";
}
/**
* 登录异常处理
* @return 返回错误码给前端显示
*/
@RequestMapping("/login/error")
@ApiOperation("登录异常处理")
@ResponseBody
public ResponseResult<String> loginFail() {
return new ResponseResult<>(602,"用户名或密码不正确");
}
/**
* 登录过期处理
* @return
*/
@ApiOperation("登录过期处理")
@RequestMapping("/login/invalid")
@ResponseBody
public String invalid() {
return "session信息已过期,请重新登录";
}
/**
* 判断该用户是否登录
* @return 返回true/false
*/
@GetMapping("/login/isLogin")
@ResponseBody
@ApiOperation("判断用户是否登录,返回true/false")
public ResponseResult<Boolean> login(){
try {
String username = SecurityContextHolder.getContext().getAuthentication().getName();
logger.info("判断用户是否登录,用户名:"+username);
if (username == null || "anonymousUser".equals(username)){
return new ResponseResult<>("success",false);
}else {
return new ResponseResult<>("success",true);
}
}catch (NullPointerException e){
return new ResponseResult<>(514,"用户信息已过期",false);
}
}
@RequestMapping("/")
public String root() {
return "/index";
}
// public User getUser() { //为了session从获取用户信息,可以配置如下
// User user = new User();
// SecurityContext ctx = SecurityContextHolder.getContext();
// Authentication auth = ctx.getAuthentication();
// if (auth.getPrincipal() instanceof UserDetails) user = (User) auth.getPrincipal();
// return user;
// }
public HttpServletRequest getRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
}
package com.example.security;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class DemoLoginSuccessHandler implements AuthenticationSuccessHandler {
private static final Logger logger = LoggerFactory.getLogger(DemoLoginSuccessHandler.class);
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
logger.info("登录成功");
logger.info("登录信息:"+authentication.getDetails().toString());
//取出登录IP地址
String username = authentication.getName();
logger.info("登录用户名:"+username);
httpServletResponse.sendRedirect("login/success");
}
}
package com.example.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.session.SessionAuthenticationException;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
@Component
public class DemoLoginFailureHandler implements AuthenticationFailureHandler {
private static final Logger logger = LoggerFactory.getLogger(DemoLoginFailureHandler.class);
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
String username = request.getParameter("username");
response.setContentType("application/json;charset=UTF-8");
String message = null;
if(exception instanceof UsernameNotFoundException){
message = "用户名["+username+"]不存在!";
}else if (exception instanceof BadCredentialsException) {
message = "用户名或密码错误!";
}else if(exception instanceof SessionAuthenticationException){
message = "该账户已经登录!无法再次登录!";
}else{
if(exception.getMessage()!=null){
message = exception.getMessage();
}else {
message = "登录失败!";
}
}
HashMap<String, String> map = new HashMap<>(16);
map.put("message",message);
map.put("code","40000");
response.getWriter().write(objectMapper.writeValueAsString(map));
logger.info("用户["+username+"]登录失败,原因:"+message);
}
}
package com.example.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Component
public class DemoLogoutSuccessHandler implements LogoutSuccessHandler {
private static final Logger logger = LoggerFactory.getLogger(DemoLogoutSuccessHandler.class);
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
if(authentication==null){
logger.warn("用户未登录!");
return;
}
String username = ((User) authentication.getPrincipal()).getUsername();
logger.info("["+username+"]退出登录");
this.removeSession(httpServletRequest);
// 重定向到登录页
Map<String,Object> map = new HashMap<>(16);
map.put("code",200);
map.put("data","success");
// Map -> Json
String json = objectMapper.writeValueAsString(map);
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("application/json; charset=utf-8");
httpServletResponse.getWriter().write(json);
}
/**
* 移除登录用户的session
* @param request
*/
private void removeSession(HttpServletRequest request) {
HttpSession session = request.getSession();
// 手动让系统中的session失效 。
session.invalidate();
}
}
package com.example.security;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.ObjectPostProcessor;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Configuration
@EnableWebSecurity
public class DemoSecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(DemoSecurityConfig.class);
@Autowired
DemoUserDetailsService demoUserDetailsService;
@Resource
private DemoLoginSuccessHandler demoLoginSuccessHandler;
@Resource
private DemoLoginFailureHandler demoLoginFailureHandler;
@Resource
private DemoLogoutSuccessHandler demoLogoutSuccessHandler;
@Bean
public PasswordEncoder passwordEncoder(){
// return NoOpPasswordEncoder.getInstance();
return new BCryptPasswordEncoder();
}
@Bean
DemoFilterInvocationSecurityMetadataSource dfisms() {
return new DemoFilterInvocationSecurityMetadataSource();
}
@Bean
DemoAccessDecisionManager dadm() {
return new DemoAccessDecisionManager();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// auth.userDetailsService(userService);
auth.userDetailsService(demoUserDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
logger.info("==============configure==================================");
// super.configure(http);
http.csrf().disable();
http.authorizeRequests() //对请求进行授权
// .antMatchers("/loginPage.html").permitAll()
// .antMatchers("/**").permitAll()
// .antMatchers("/admin/**").hasRole("admin")
// .antMatchers("/db/**").hasRole("dba")
// .antMatchers("/user/**").hasRole("user")
.anyRequest() //任何请求
.authenticated()//都要进行身份认证
.and()
.formLogin()//表单登录
.loginPage("/loginPage")//登录页面
// .loginPage("/loginPage.html")
.loginProcessingUrl("/login")
//设置登录成功
.successHandler(demoLoginSuccessHandler)
.failureHandler(demoLoginFailureHandler)
.permitAll()//和登录相关的接口都不需要认证即可访问
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(demoLogoutSuccessHandler)
.deleteCookies("JSESSIONID");
// http.authorizeRequests()
// .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
// @Override
// public <O extends FilterSecurityInterceptor> O postProcess(O object) {
// object.setSecurityMetadataSource(dfisms());
// object.setAccessDecisionManager(dadm());
// return object;
// }
// })
// .anyRequest() //任何请求
// .authenticated()//都要进行身份认证
// .and()
// .formLogin()//表单登录
// .loginPage("/loginPage")//登录页面
//// .loginPage("/loginPage.html")
// .loginProcessingUrl("/login")
// //设置登录成功
// .successHandler(demoLoginSuccessHandler)
// .permitAll();//和登录相关的接口都不需要认证即可访问
// http.authorizeRequests().
// antMatchers("/static/**").permitAll().anyRequest().authenticated().
// and().formLogin().loginPage("/login").permitAll().successHandler(loginSuccessHandler()).
// and().logout().permitAll().invalidateHttpSession(true).
// deleteCookies("JSESSIONID").logoutSuccessHandler(logoutSuccessHandler()).
// and().sessionManagement().maximumSessions(10).expiredUrl("/login");
}
//======================================================================
/**
* 配置忽略的静态文件,不加的话,登录之前页面的css,js不能正常使用,得登录之后才能正常.
*/
@Override
public void configure(WebSecurity web) throws Exception {
// 忽略URL
// web.ignoring().antMatchers("/**/*.js", "/lang/*.json", "/**/*.css", "/**/*.js", "/**/*.map", "/**/*.html",
// "/**/*.png");
// 设置拦截忽略文件夹,可以对静态资源放行
web.ignoring()
.antMatchers("/swagger-ui.html")
.antMatchers("/v2/**")
.antMatchers("/swagger-resources/**")
.antMatchers("/loginPage.html")
.antMatchers("/static/css/**", "/static/js/**","/static/fonts/**","/static/img/**","/img/**", "/js/**","/fonts/**","/css/**","/static/**");
}
@Bean
public LogoutSuccessHandler logoutSuccessHandler() { //登出处理
return new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
}
// @Override
// public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
// try {
// SecurityUser user = (SecurityUser) authentication.getPrincipal();
//// logger.info("USER : " + user.getUsername() + " LOGOUT SUCCESS ! ");
// } catch (Exception e) {
//// logger.info("LOGOUT EXCEPTION , e : " + e.getMessage());
// }
// httpServletResponse.sendRedirect("/login");
// }
};
}
@Bean
public SavedRequestAwareAuthenticationSuccessHandler loginSuccessHandler() { //登入处理
return new SavedRequestAwareAuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
User userDetails = (User) authentication.getPrincipal();
logger.info("USER : " + userDetails.getUsername() + " LOGIN SUCCESS ! ");
super.onAuthenticationSuccess(request, response, authentication);
}
};
}
// @Bean
// UserDetailsService demoUserDetailsService() {
// return new DemoUserDetailsService();
// }
@Bean
public UserDetailsService userDetailsService() { //用户登录实现
// return new DemoUserDetailsService();
return new UserDetailsService() {
// @Override
// public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
// return null;
// }
// @Autowired
// private UserRepository userRepository;
@Resource
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
logger.info("=-======loadUserByUsername======-=-========d================"+username);
// User user = userRepository.findByUsername(s);
// if (user == null) throw new UsernameNotFoundException("Username " + s + " not found");
// return new SecurityUser(user);
return new User(username,passwordEncoder.encode("123456"),
true,true,true,true,
AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
}
};
}
// @Autowired
// public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
// auth.eraseCredentials(false);
// }
}