700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Spring Security自定义登录验证及登录返回结果

Spring Security自定义登录验证及登录返回结果

时间:2024-02-20 22:07:58

相关推荐

Spring Security自定义登录验证及登录返回结果

Spring Security自定义登录验证及登录返回结果

一.功能描述二.处理逻辑简单流程自定义UserDetails自定义UserDetailsDAO自定义UserDetailsService自定义用户登录验证逻辑AuthenticationProvider 三.Spring Security基本配置信息四.登录登出自定义处理器登录成功处理器LocalAuthenticationSuccessHandler登录失败处理器LocalAuthenticationFailureHandler登出成功处理器LocalLogoutSuccessHandler匿名用户访问无权限处理器LocalAuthenticationEntryPoint认证用户访问无权限处理器LocalAccessDeniedHandler旧用户被踢处理器LocalSessionInformationExpiredStrategy

一.功能描述

使用Spring Boot + Spring Security实现自定义登录验证及登录登出返回结果. 适用于前后端分离开发的项目.如有不妥之处, 请各位大神指教.

二.处理逻辑

简单流程

自定义UserDetails

@javax.persistence.Entity@org.hibernate.annotations.Table(appliesTo = "local_user_details")public class LocalUserDetails implements java.io.Serializable, UserDetails {private static final long serialVersionUID = 1594783117560L;@javax.persistence.Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "[id]", nullable = false, unique = true, length = 0, precision = 20, scale = 0, columnDefinition = "bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键'")@ApiModelProperty(value = "主键", required = false, hidden = false, example = "主键")@JsonInclude(value = JsonInclude.Include.NON_EMPTY)private Long id;@NonNull@Size(min = 3, max = 18)@Column(name = "[userid]", nullable = false, unique = false, length = 64, precision = 0, scale = 0, columnDefinition = "varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '用户索引'")@ApiModelProperty(value = "用户索引", required = true, hidden = false, example = "用户索引")@JsonInclude(value = JsonInclude.Include.NON_EMPTY)private String userid = "";@NonNull@Size(min = 3, max = 64)@Column(name = "[passwd]", nullable = false, unique = false, length = 128, precision = 0, scale = 0, columnDefinition = "varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '用户密码'")@ApiModelProperty(value = "用户密码", required = true, hidden = false, example = "用户密码")@JsonInclude(value = JsonInclude.Include.NON_EMPTY)private String passwd = "";public LocalUserDetails() {}public Long getId() {return this.id;}public void setId(Long id) {this.id = id;}public String getUserid() {return this.userid;}public void setUserid(String userid) {this.userid = userid;}public String getPasswd() {return this.passwd;}public void setPasswd(String passwd) {this.passwd = passwd;}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {//返回分配给用户的角色列表return new ArrayList<>();}@Overridepublic String getPassword() {return this.getPasswd();}@Overridepublic String getUsername() {return this.getUserid();}@Overridepublic boolean isAccountNonExpired() {// 指定账户是否未过期.return true;}@Overridepublic boolean isAccountNonLocked() {// 指定账户是否未锁定.return true;}@Overridepublic boolean isCredentialsNonExpired() {// 指定密码是否未过期.return true;}@Overridepublic boolean isEnabled() {// 指定用户是否已启用, 禁用的用户无法进行身份验证.return true;}}

自定义UserDetailsDAO

public interface LocalUserDetailsDAO extends JpaRepository<LocalUserDetails, Long>, JpaSpecificationExecutor<LocalUserDetails> {Optional<LocalUserDetails> findByUserid(String userid);}

自定义UserDetailsService

@Service@Transactionalpublic class AuthorityUserLoginInfoService implements UserDetailsService {@Autowiredprivate LocalUserDetailsDAO dao;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {Optional<LocalUserDetails> user = dao.findByUserid(username);if (user.isPresent()) {if (!user.get().isEnabled()) {throw new DisabledException("暂无权限!"); }} else {throw new UsernameNotFoundException("用户名或密码不正确!");}return user.get();}}

自定义用户登录验证逻辑AuthenticationProvider

@Componentpublic class LocalAuthenticationProvider implements AuthenticationProvider {@Autowiredprivate AuthorityUserLoginInfoService userService;private final PasswordEncoder encoder = new BCryptPasswordEncoder();/** 自定义验证方式 */@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {String username = authentication.getName();String password = (String) authentication.getCredentials();// 获取Request, 获取其他参数信息ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();HttpSession session = attributes.getRequest().getSession();Object others = session.getAttribute("others");UserDetails node = userService.loadUserByUsername(username);if (!encoder.matches(password, node.getPassword())) {throw new BadCredentialsException("用户名或密码不正确!"); }return new UsernamePasswordAuthenticationToken(node, password, node.getAuthorities());}@Overridepublic boolean supports(Class<?> authentication) {return true;}}

三.Spring Security基本配置信息

@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true)public class SecurityConfig extends WebSecurityConfigurerAdapter {@Value(value = "${ignoringAntMatchers:/**}")private String ignoringAntMatchers;@Value(value = "${loginPage:/login}")private String loginPage;@Value(value = "${loginProcessingUrl:/api/user/login}")private String loginProcessingUrl;@Value(value = "${logoutUrl:/api/user/logout}")private String logoutUrl;@Value(value = "${expiredUrl:/login}")private String expiredUrl;@Autowiredprivate DataSource dataSource;@Autowiredprivate AuthorityUserLoginInfoService userService;@Beanpublic BCryptPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder(4);}@Beanpublic AuthenticationProvider authenticationProvider() {return new LocalAuthenticationProvider();}@Overridepublic void configure(AuthenticationManagerBuilder auth) throws Exception {// 自定义用户登录验证auth.authenticationProvider(authenticationProvider());// 指定密码加密所使用的加密器为passwordEncoder(), 需要将密码加密后写入数据库auth.userDetailsService(this.userService).passwordEncoder(passwordEncoder());// 不删除凭据,以便记住用户auth.eraseCredentials(false);}@Overridepublic void configure(WebSecurity web) throws Exception {// 设置不拦截规则web.ignoring().antMatchers(this.ignoringAntMatchers.split(","));}@Overrideprotected void configure(HttpSecurity http) throws Exception {// 设置拦截规则http.authorizeRequests().anyRequest().authenticated();// 自定义登录信息http.csrf().disable().formLogin() //.loginPage(this.loginPage) // 自定义登录页url,默认为/login.loginProcessingUrl(this.loginProcessingUrl) // 登录验证地址, 即RequestMapping地址// 用户名的请求字段. 默认为org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_USERNAME_KEY.usernameParameter("username")// 用户名的请求字段. 默认为org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_PASSWORD_KEY.passwordParameter("password") // .successHandler(new LocalAuthenticationSuccessHandler()) // 登录验证成功后, 执行的内容// .defaultSuccessUrl("/index") // 登录验证成功后, 跳转的页面, 如果自定义返回内容, 请使用successHandler方法// .successForwardUrl("/index") // 登录验证成功后, 跳转的页面, 如果自定义返回内容, 请使用successHandler方法.failureHandler(new LocalAuthenticationFailureHandler()) // 登录验证失败后, 执行的内容// .failureUrl("/login?error") // 登录验证失败后, 跳转的页面, 如果自定义返回内容, 请使用failureHandler方法.permitAll();// 自定义异常处理器http.exceptionHandling() // 异常处理器// 用来解决匿名用户访问无权限资源时的异常.authenticationEntryPoint(new LocalAuthenticationEntryPoint())// 用来解决认证过的用户访问无权限资源时的异常, 跳转的页面, 如果自定义返回内容, 请使用accessDeniedHandler方法// .accessDeniedPage("/error")// 用来解决认证过的用户访问无权限资源时的异常.accessDeniedHandler(new LocalAccessDeniedHandler());// 自定义注销信息http.logout() // .logoutUrl(this.logoutUrl) // 登出验证地址, 即RequestMapping地址.logoutSuccessHandler(new LocalLogoutSuccessHandler()) // 登录验证成功后, 执行的内容// .logoutSuccessUrl("/login?logout") // 登录验证成功后, 跳转的页面, 如果自定义返回内容, 请使用logoutSuccessHandler方法.deleteCookies("JSESSIONID") // 退出登录后需要删除的cookies名称.invalidateHttpSession(true) // 退出登录后, 会话失效.permitAll();// remember-me配置http.rememberMe() // // org.springframework.security.config.annotation.web.configurers.RememberMeConfigurer.DEFAULT_REMEMBER_ME_NAME.rememberMeCookieName("remember-me")// org.springframework.security.config.annotation.web.configurers.RememberMeConfigurer.DEFAULT_REMEMBER_ME_NAME.rememberMeParameter("remember-me")// org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.TWO_WEEKS_S.tokenValiditySeconds(360000)// tokenRepository.tokenRepository(new LocalPersistentTokenRepository(this.dataSource));// session管理http.sessionManagement().sessionFixation().changeSessionId() //.maximumSessions(1) // 最大会话数.maxSessionsPreventsLogin(false) // 达到最大数后, 强制验证, 踢出旧用户// 旧用户被踢出后, 跳转的页面, 如果自定义返回内容, 请使用expiredSessionStrategy方法// .expiredUrl("/login?expired")// 旧用户被踢出后, 执行的内容.expiredSessionStrategy(new LocalSessionInformationExpiredStrategy());}@Bean@Overrideprotected AuthenticationManager authenticationManager() throws Exception {return super.authenticationManager();}}

四.登录登出自定义处理器

登录成功处理器LocalAuthenticationSuccessHandler

public class LocalAuthenticationSuccessHandler implements AuthenticationSuccessHandler {private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)throws IOException, ServletException {response.setCharacterEncoding("utf-8");response.setContentType("application/json;charset=utf-8");response.getWriter().print(gson.toJson(new Result<>(ResultStatus.SUCCESS_LOGIN)));}}

登录失败处理器LocalAuthenticationFailureHandler

public class LocalAuthenticationFailureHandler implements AuthenticationFailureHandler {private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)throws IOException, ServletException {response.setCharacterEncoding("utf-8");response.setContentType("application/json;charset=utf-8");response.getWriter().print(gson.toJson(new Result<>(ResultStatus.ERROR_LOGIN)));}}

登出成功处理器LocalLogoutSuccessHandler

public class LocalLogoutSuccessHandler implements LogoutSuccessHandler {private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();@Overridepublic void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)throws IOException, ServletException {response.setCharacterEncoding("utf-8");response.setContentType("application/json;charset=utf-8");response.getWriter().print(gson.toJson(new Result<>(20001, "登出成功!")));}}

匿名用户访问无权限处理器LocalAuthenticationEntryPoint

public class LocalAuthenticationEntryPoint implements AuthenticationEntryPoint {private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();@Overridepublic void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)throws IOException, ServletException {response.setCharacterEncoding("utf-8");response.setContentType("application/json;charset=utf-8");response.getWriter().print(gson.toJson(new Result<>(ResultStatus.WRONG_DEAL)));}}

认证用户访问无权限处理器LocalAccessDeniedHandler

public class LocalAccessDeniedHandler implements AccessDeniedHandler {private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException)throws IOException, ServletException {response.setCharacterEncoding("utf-8");response.setContentType("application/json;charset=utf-8");response.getWriter().print(gson.toJson(new Result<>(ResultStatus.WRONG_DEAL)));}}

旧用户被踢处理器LocalSessionInformationExpiredStrategy

public class LocalSessionInformationExpiredStrategy implements SessionInformationExpiredStrategy {private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();@Overridepublic void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException, ServletException {HttpServletResponse response = event.getResponse();response.setCharacterEncoding("utf-8");response.setContentType("application/json;charset=utf-8");response.getWriter().print(gson.toJson(new Result<>(20002, "用户已退出!")));}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。