SpringBoot用户登录
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); // } }