替换UsernamePasswordAuthenticationFilter类
1. pom.xml
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> </dependency> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>unpack</id> <phase>generate-sources</phase> <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <overWrite>false</overWrite> <outputDirectory>${project.build.directory}/classes</outputDirectory> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin>
2.重写FormLoginConfigurer类,替换其中的UsernamePasswordAuthenticationFilter为UsernamePasswordAuthenticationWithLogFilter类
package org.springframework.security.config.annotation.web.configurers; import com.sparkmap.platform.security.filter.UsernamePasswordAuthenticationWithLogFilter; import org.springframework.security.config.annotation.web.HttpSecurityBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.authentication.ForwardAuthenticationFailureHandler; import org.springframework.security.web.authentication.ForwardAuthenticationSuccessHandler; import org.springframework.security.web.authentication.RememberMeServices; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; /** * Adds form based authentication. All attributes have reasonable defaults making all * parameters are optional. If no {@link #loginPage(String)} is specified, a default login * page will be generated by the framework. * * <h2>Security Filters</h2> * * The following Filters are populated * * <ul> * <li>{@link UsernamePasswordAuthenticationFilter}</li> * </ul> * * <h2>Shared Objects Created</h2> * * The following shared objects are populated * * <ul> * <li>{@link AuthenticationEntryPoint}</li> * </ul> * * <h2>Shared Objects Used</h2> * * The following shared objects are used: * * <ul> * <li>{@link org.springframework.security.authentication.AuthenticationManager}</li> * <li>{@link RememberMeServices} - is optionally used. See {@link RememberMeConfigurer} * </li> * <li>{@link SessionAuthenticationStrategy} - is optionally used. See * {@link SessionManagementConfigurer}</li> * <li>{@link DefaultLoginPageGeneratingFilter} - if present will be populated with * information from the configuration</li> * </ul> * * @author Rob Winch * @author Shazin Sadakath * @since 3.2 */ public final class FormLoginConfigurer<H extends HttpSecurityBuilder<H>> extends AbstractAuthenticationFilterConfigurer<H, FormLoginConfigurer<H>, UsernamePasswordAuthenticationFilter> { /** * Creates a new instance * @see HttpSecurity#formLogin() */ public FormLoginConfigurer() { super(new UsernamePasswordAuthenticationWithLogFilter(), null); // 改为自己写的类 usernameParameter("username"); passwordParameter("password"); } /** * <p> * Specifies the URL to send users to if login is required. If used with * {@link EnableWebSecurity} a default login page will be generated when this * attribute is not specified. * </p> * * <p> * If a URL is specified or this is not being used in conjunction with * {@link EnableWebSecurity}, users are required to process the specified URL to * generate a login page. In general, the login page should create a form that submits * a request with the following requirements to work with * {@link UsernamePasswordAuthenticationFilter}: * </p> * * <ul> * <li>It must be an HTTP POST</li> * <li>It must be submitted to {@link #loginProcessingUrl(String)}</li> * <li>It should include the username as an HTTP parameter by the name of * {@link #usernameParameter(String)}</li> * <li>It should include the password as an HTTP parameter by the name of * {@link #passwordParameter(String)}</li> * </ul> * * <h2>Example login.jsp</h2> * * Login pages can be rendered with any technology you choose so long as the rules * above are followed. Below is an example login.jsp that can be used as a quick start * when using JSP's or as a baseline to translate into another view technology. * * <pre> * <!-- loginProcessingUrl should correspond to FormLoginConfigurer#loginProcessingUrl. Don't forget to perform a POST --> * <c:url value="/login" var="loginProcessingUrl"/> * <form action="${loginProcessingUrl}" method="post"> * <fieldset> * <legend>Please Login</legend> * <!-- use param.error assuming FormLoginConfigurer#failureUrl contains the query parameter error --> * <c:if test="${param.error != null}"> * <div> * Failed to login. * <c:if test="${SPRING_SECURITY_LAST_EXCEPTION != null}"> * Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" /> * </c:if> * </div> * </c:if> * <!-- the configured LogoutConfigurer#logoutSuccessUrl is /login?logout and contains the query param logout --> * <c:if test="${param.logout != null}"> * <div> * You have been logged out. * </div> * </c:if> * <p> * <label for="username">Username</label> * <input type="text" id="username" name="username"/> * </p> * <p> * <label for="password">Password</label> * <input type="password" id="password" name="password"/> * </p> * <!-- if using RememberMeConfigurer make sure remember-me matches RememberMeConfigurer#rememberMeParameter --> * <p> * <label for="remember-me">Remember Me?</label> * <input type="checkbox" id="remember-me" name="remember-me"/> * </p> * <div> * <button type="submit" class="btn">Log in</button> * </div> * </fieldset> * </form> * </pre> * * <h2>Impact on other defaults</h2> * * Updating this value, also impacts a number of other default values. For example, * the following are the default values when only formLogin() was specified. * * <ul> * <li>/login GET - the login form</li> * <li>/login POST - process the credentials and if valid authenticate the user</li> * <li>/login?error GET - redirect here for failed authentication attempts</li> * <li>/login?logout GET - redirect here after successfully logging out</li> * </ul> * * If "/authenticate" was passed to this method it update the defaults as shown below: * * <ul> * <li>/authenticate GET - the login form</li> * <li>/authenticate POST - process the credentials and if valid authenticate the user * </li> * <li>/authenticate?error GET - redirect here for failed authentication attempts</li> * <li>/authenticate?logout GET - redirect here after successfully logging out</li> * </ul> * @param loginPage the login page to redirect to if authentication is required (i.e. * "/login") * @return the {@link FormLoginConfigurer} for additional customization */ @Override public FormLoginConfigurer<H> loginPage(String loginPage) { return super.loginPage(loginPage); } /** * The HTTP parameter to look for the username when performing authentication. Default * is "username". * @param usernameParameter the HTTP parameter to look for the username when * performing authentication * @return the {@link FormLoginConfigurer} for additional customization */ public FormLoginConfigurer<H> usernameParameter(String usernameParameter) { getAuthenticationFilter().setUsernameParameter(usernameParameter); return this; } /** * The HTTP parameter to look for the password when performing authentication. Default * is "password". * @param passwordParameter the HTTP parameter to look for the password when * performing authentication * @return the {@link FormLoginConfigurer} for additional customization */ public FormLoginConfigurer<H> passwordParameter(String passwordParameter) { getAuthenticationFilter().setPasswordParameter(passwordParameter); return this; } /** * Forward Authentication Failure Handler * @param forwardUrl the target URL in case of failure * @return the {@link FormLoginConfigurer} for additional customization */ public FormLoginConfigurer<H> failureForwardUrl(String forwardUrl) { failureHandler(new ForwardAuthenticationFailureHandler(forwardUrl)); return this; } /** * Forward Authentication Success Handler * @param forwardUrl the target URL in case of success * @return the {@link FormLoginConfigurer} for additional customization */ public FormLoginConfigurer<H> successForwardUrl(String forwardUrl) { successHandler(new ForwardAuthenticationSuccessHandler(forwardUrl)); return this; } @Override public void init(H http) throws Exception { super.init(http); initDefaultLoginFilter(http); } @Override protected RequestMatcher createLoginProcessingUrlMatcher(String loginProcessingUrl) { return new AntPathRequestMatcher(loginProcessingUrl, "POST"); } /** * Gets the HTTP parameter that is used to submit the username. * @return the HTTP parameter that is used to submit the username */ private String getUsernameParameter() { return getAuthenticationFilter().getUsernameParameter(); } /** * Gets the HTTP parameter that is used to submit the password. * @return the HTTP parameter that is used to submit the password */ private String getPasswordParameter() { return getAuthenticationFilter().getPasswordParameter(); } /** * If available, initializes the {@link DefaultLoginPageGeneratingFilter} shared * object. * @param http the {@link HttpSecurityBuilder} to use */ private void initDefaultLoginFilter(H http) { DefaultLoginPageGeneratingFilter loginPageGeneratingFilter = http .getSharedObject(DefaultLoginPageGeneratingFilter.class); if (loginPageGeneratingFilter != null && !isCustomLoginPage()) { loginPageGeneratingFilter.setFormLoginEnabled(true); loginPageGeneratingFilter.setUsernameParameter(getUsernameParameter()); loginPageGeneratingFilter.setPasswordParameter(getPasswordParameter()); loginPageGeneratingFilter.setLoginPageUrl(getLoginPage()); loginPageGeneratingFilter.setFailureUrl(getFailureUrl()); loginPageGeneratingFilter.setAuthenticationUrl(getLoginProcessingUrl()); } } }
3.实现自己写的UsernamePasswordAuthenticationWithLogFilter类
package com.ruitu.platform.security.filter; import java.io.IOException; import java.util.Date; import com.alibaba.fastjson2.JSONObject; import com.ruitu.platform.security.domain.LoginLog; import com.ruitu.platform.security.domain.SecurityUser; import com.ruitu.platform.security.enumeration.LoginStatus; import com.ruitu.platform.security.service.LoginLogService; import com.ruitu.platform.utils.ExceptionUtil; import com.ruitu.platform.utils.RequestInfoUtil; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; /** * 扩展UsernamePasswordAuthenticationFilter类,实现日志功能 * */ public class UsernamePasswordAuthenticationWithLogFilter extends UsernamePasswordAuthenticationFilter { private LoginLogService loginLogService = null; private ThreadLocal<Long> currentTime = new ThreadLocal<>(); public LoginLogService getLoginLogService() { return loginLogService; } public void setLoginLogService(LoginLogService loginLogService) { this.loginLogService = loginLogService; } public UsernamePasswordAuthenticationWithLogFilter() { super(); } public UsernamePasswordAuthenticationWithLogFilter(AuthenticationManager authenticationManager) { super(authenticationManager); } public UsernamePasswordAuthenticationWithLogFilter(AuthenticationManager authenticationManager, LoginLogService loginLogService) { super(authenticationManager); this.loginLogService = loginLogService; } public UsernamePasswordAuthenticationWithLogFilter(LoginLogService loginLogService) { this.loginLogService = loginLogService; } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { currentTime.set(System.currentTimeMillis());// 记录方法的执行时间 return super.attemptAuthentication(request, response); } @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { super.successfulAuthentication(request, response, chain, authResult); Date startTime = new Date(); startTime.setTime(currentTime.get()); currentTime.remove(); // if (loginLogService != null) { SecurityUser securityUser = (SecurityUser) authResult.getPrincipal(); String username = securityUser.getUsername(); String password = obtainPassword(request); LoginLog loginLog = new LoginLog(); loginLog.setStatus(LoginStatus.SUCCESS.name()); loginLog.setResponseResult(JSONObject.toJSONString(authResult)); loginLog.setUsername(username); loginLog.setPassword(password); loginLog.setBrowser(RequestInfoUtil.getBrowser(request)); loginLog.setIp(RequestInfoUtil.getIp(request)); loginLog.setRequestTime(startTime); loginLog.setCreateTime(new Date()); loginLog.setResponseTime(loginLog.getCreateTime()); loginLogService.recordLoginLog(loginLog); } else { System.out.println("-----------------------------------------: successfulAuthentication "); } } @Override protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { super.unsuccessfulAuthentication(request, response, failed); Date startTime = new Date(); startTime.setTime(currentTime.get()); currentTime.remove(); if (loginLogService != null) { String username = obtainUsername(request); username = (username != null) ? username.trim() : ""; String password = obtainPassword(request); LoginLog loginLog = new LoginLog(); loginLog.setStatus(LoginStatus.FAIL.name()); loginLog.setExceptionDetail(ExceptionUtil.getStackMsg(failed).substring(255)); loginLog.setUsername(username); loginLog.setPassword(password); loginLog.setBrowser(RequestInfoUtil.getBrowser(request)); loginLog.setIp(RequestInfoUtil.getIp(request)); loginLog.setRequestTime(startTime); loginLog.setCreateTime(new Date()); loginLog.setResponseTime(loginLog.getCreateTime()); loginLogService.recordLoginLog(loginLog); } else { System.out.println("-----------------------------------------: unsuccessfulAuthentication "); } } }
-----
标签:gt,登录,用户,lt,SpringSecurity6.1,link,import,security,loginLog From: https://www.cnblogs.com/gispathfinder/p/17876485.html