org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer Maven / Gradle / Ivy
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.annotation.web.configurers;
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.WebSecurityConfigurerAdapter;
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.
*
* Security Filters
*
* The following Filters are populated
*
*
* - {@link UsernamePasswordAuthenticationFilter}
*
*
* Shared Objects Created
*
* The following shared objects are populated
*
*
* - {@link AuthenticationEntryPoint}
*
*
* Shared Objects Used
*
* The following shared objects are used:
*
*
* - {@link org.springframework.security.authentication.AuthenticationManager}
* - {@link RememberMeServices} - is optionally used. See {@link RememberMeConfigurer}
*
* - {@link SessionAuthenticationStrategy} - is optionally used. See
* {@link SessionManagementConfigurer}
* - {@link DefaultLoginPageGeneratingFilter} - if present will be populated with
* information from the configuration
*
*
* @author Rob Winch
* @author Shazin Sadakath
* @since 3.2
*/
public final class FormLoginConfigurer> extends
AbstractAuthenticationFilterConfigurer, UsernamePasswordAuthenticationFilter> {
/**
* Creates a new instance
* @see HttpSecurity#formLogin()
*/
public FormLoginConfigurer() {
super(new UsernamePasswordAuthenticationFilter(), null);
usernameParameter("username");
passwordParameter("password");
}
/**
*
* Specifies the URL to send users to if login is required. If used with
* {@link WebSecurityConfigurerAdapter} a default login page will be generated when
* this attribute is not specified.
*
*
*
* If a URL is specified or this is not being used in conjuction with
* {@link WebSecurityConfigurerAdapter}, 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}:
*
*
*
* - It must be an HTTP POST
* - It must be submitted to {@link #loginProcessingUrl(String)}
* - It should include the username as an HTTP parameter by the name of
* {@link #usernameParameter(String)}
* - It should include the password as an HTTP parameter by the name of
* {@link #passwordParameter(String)}
*
*
* Example login.jsp
*
* 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.
*
*
*
* <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>
*
*
* Impact on other defaults
*
* Updating this value, also impacts a number of other default values. For example,
* the following are the default values when only formLogin() was specified.
*
*
* - /login GET - the login form
* - /login POST - process the credentials and if valid authenticate the user
* - /login?error GET - redirect here for failed authentication attempts
* - /login?logout GET - redirect here after successfully logging out
*
*
* If "/authenticate" was passed to this method it update the defaults as shown below:
*
*
* - /authenticate GET - the login form
* - /authenticate POST - process the credentials and if valid authenticate the user
*
* - /authenticate?error GET - redirect here for failed authentication attempts
* - /authenticate?logout GET - redirect here after successfully logging out
*
* @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 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 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 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 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 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());
}
}
}