SEC-722: Add Open ID Namespace Support
http://jira.springframework.org/browse/SEC-722. Added element to namespace and modified form login parser to handle open id element. Also added openID support to login page generator.
This commit is contained in:
parent
b62ad5b097
commit
815f04b6c3
|
@ -24,7 +24,6 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
|
|||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
static final String ATT_LOGIN_URL = "login-processing-url";
|
||||
static final String DEF_LOGIN_URL = "/j_spring_security_check";
|
||||
|
||||
static final String ATT_LOGIN_PAGE = "login-page";
|
||||
static final String DEF_LOGIN_PAGE = DefaultLoginPageGeneratingFilter.DEFAULT_LOGIN_PAGE_URL;
|
||||
|
@ -35,11 +34,23 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
|
|||
static final String ATT_FORM_LOGIN_AUTHENTICATION_FAILURE_URL = "authentication-failure-url";
|
||||
static final String DEF_FORM_LOGIN_AUTHENTICATION_FAILURE_URL = DefaultLoginPageGeneratingFilter.DEFAULT_LOGIN_PAGE_URL + "?" + DefaultLoginPageGeneratingFilter.ERROR_PARAMETER_NAME;
|
||||
|
||||
String defaultLoginProcessingUrl;
|
||||
String filterClassName;
|
||||
|
||||
RootBeanDefinition filterBean;
|
||||
RootBeanDefinition entryPointBean;
|
||||
String loginPage;
|
||||
|
||||
FormLoginBeanDefinitionParser(String defaultLoginProcessingUrl, String filterClassName) {
|
||||
this.defaultLoginProcessingUrl = defaultLoginProcessingUrl;
|
||||
this.filterClassName = filterClassName;
|
||||
}
|
||||
|
||||
public BeanDefinition parse(Element elt, ParserContext parserContext) {
|
||||
String loginUrl = null;
|
||||
String defaultTargetUrl = null;
|
||||
String authenticationFailureUrl = null;
|
||||
String loginPage = null;
|
||||
|
||||
Object source = null;
|
||||
|
||||
if (elt != null) {
|
||||
|
@ -52,7 +63,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
|
|||
|
||||
ConfigUtils.registerProviderManagerIfNecessary(parserContext);
|
||||
|
||||
RootBeanDefinition filterBean = createFilterBean(loginUrl, defaultTargetUrl, loginPage, authenticationFailureUrl);
|
||||
filterBean = createFilterBean(loginUrl, defaultTargetUrl, loginPage, authenticationFailureUrl);
|
||||
|
||||
filterBean.setSource(source);
|
||||
filterBean.getPropertyValues().addPropertyValue("authenticationManager",
|
||||
|
@ -62,34 +73,18 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
|
|||
BeanDefinitionBuilder.rootBeanDefinition(AuthenticationProcessingFilterEntryPoint.class);
|
||||
entryPointBuilder.setSource(source);
|
||||
|
||||
entryPointBuilder.addPropertyValue("loginFormUrl", StringUtils.hasText(loginPage) ? loginPage : DEF_LOGIN_PAGE);
|
||||
|
||||
// If no login page has been defined, add in the default page generator.
|
||||
if (!StringUtils.hasText(loginPage)) {
|
||||
logger.info("No login page configured in form-login element. The default internal one will be used. Use" +
|
||||
"the 'loginPage' attribute to specify the URL of the login page.");
|
||||
loginPage = DEF_LOGIN_PAGE;
|
||||
RootBeanDefinition loginPageFilter = new RootBeanDefinition(DefaultLoginPageGeneratingFilter.class);
|
||||
loginPageFilter.getConstructorArgumentValues().addGenericArgumentValue(
|
||||
new RuntimeBeanReference(BeanIds.FORM_LOGIN_FILTER));
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.DEFAULT_LOGIN_PAGE_GENERATING_FILTER, loginPageFilter);
|
||||
}
|
||||
|
||||
entryPointBuilder.addPropertyValue("loginFormUrl", loginPage);
|
||||
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.FORM_LOGIN_FILTER, filterBean);
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.FORM_LOGIN_ENTRY_POINT,
|
||||
entryPointBuilder.getBeanDefinition());
|
||||
entryPointBean = (RootBeanDefinition) entryPointBuilder.getBeanDefinition();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private RootBeanDefinition createFilterBean(String loginUrl, String defaultTargetUrl, String loginPage, String authenticationFailureUrl) {
|
||||
BeanDefinitionBuilder filterBuilder =
|
||||
BeanDefinitionBuilder.rootBeanDefinition(AuthenticationProcessingFilter.class);
|
||||
|
||||
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(filterClassName);
|
||||
|
||||
if (!StringUtils.hasText(loginUrl)) {
|
||||
loginUrl = DEF_LOGIN_URL;
|
||||
loginUrl = defaultLoginProcessingUrl;
|
||||
}
|
||||
|
||||
filterBuilder.addPropertyValue("filterProcessesUrl", loginUrl);
|
||||
|
@ -114,4 +109,16 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
|
|||
|
||||
return (RootBeanDefinition) filterBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
RootBeanDefinition getFilterBean() {
|
||||
return filterBean;
|
||||
}
|
||||
|
||||
RootBeanDefinition getEntryPointBean() {
|
||||
return entryPointBean;
|
||||
}
|
||||
|
||||
String getLoginPage() {
|
||||
return loginPage;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ import java.util.LinkedHashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
|
@ -28,6 +30,7 @@ import org.springframework.security.securechannel.SecureChannelProcessor;
|
|||
import org.springframework.security.securechannel.RetryWithHttpEntryPoint;
|
||||
import org.springframework.security.securechannel.RetryWithHttpsEntryPoint;
|
||||
import org.springframework.security.ui.ExceptionTranslationFilter;
|
||||
import org.springframework.security.ui.webapp.DefaultLoginPageGeneratingFilter;
|
||||
import org.springframework.security.util.FilterChainProxy;
|
||||
import org.springframework.security.util.RegexUrlPathMatcher;
|
||||
import org.springframework.security.util.AntUrlPathMatcher;
|
||||
|
@ -44,6 +47,7 @@ import org.w3c.dom.Element;
|
|||
* @version $Id$
|
||||
*/
|
||||
public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
static final String ATT_REALM = "realm";
|
||||
static final String DEF_REALM = "Spring Security Application";
|
||||
|
@ -190,11 +194,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
|||
registry.registerBeanDefinition(BeanIds.CHANNEL_DECISION_MANAGER, channelDecisionManager);
|
||||
}
|
||||
|
||||
String realm = element.getAttribute(ATT_REALM);
|
||||
if (!StringUtils.hasText(realm)) {
|
||||
realm = DEF_REALM;
|
||||
}
|
||||
|
||||
Element sessionControlElt = DomUtils.getChildElementByTagName(element, Elements.CONCURRENT_SESSIONS);
|
||||
if (sessionControlElt != null) {
|
||||
new ConcurrentSessionsBeanDefinitionParser().parse(sessionControlElt, parserContext);
|
||||
|
@ -220,16 +219,8 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
|||
if (logoutElt != null || autoConfig) {
|
||||
new LogoutBeanDefinitionParser().parse(logoutElt, parserContext);
|
||||
}
|
||||
|
||||
Element formLoginElt = DomUtils.getChildElementByTagName(element, Elements.FORM_LOGIN);
|
||||
if (formLoginElt != null || autoConfig) {
|
||||
new FormLoginBeanDefinitionParser().parse(formLoginElt, parserContext);
|
||||
}
|
||||
|
||||
Element basicAuthElt = DomUtils.getChildElementByTagName(element, Elements.BASIC_AUTH);
|
||||
if (basicAuthElt != null || autoConfig) {
|
||||
new BasicAuthenticationBeanDefinitionParser(realm).parse(basicAuthElt, parserContext);
|
||||
}
|
||||
|
||||
parseBasicFormLoginAndOpenID(element, parserContext, autoConfig);
|
||||
|
||||
Element x509Elt = DomUtils.getChildElementByTagName(element, Elements.X509);
|
||||
if (x509Elt != null) {
|
||||
|
@ -248,6 +239,104 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void parseBasicFormLoginAndOpenID(Element element, ParserContext parserContext, boolean autoConfig) {
|
||||
RootBeanDefinition formLoginFilter = null;
|
||||
RootBeanDefinition formLoginEntryPoint = null;
|
||||
String formLoginPage = null;
|
||||
RootBeanDefinition openIDFilter = null;
|
||||
RootBeanDefinition openIDEntryPoint = null;
|
||||
String openIDLoginPage = null;
|
||||
|
||||
String realm = element.getAttribute(ATT_REALM);
|
||||
if (!StringUtils.hasText(realm)) {
|
||||
realm = DEF_REALM;
|
||||
}
|
||||
|
||||
Element basicAuthElt = DomUtils.getChildElementByTagName(element, Elements.BASIC_AUTH);
|
||||
if (basicAuthElt != null || autoConfig) {
|
||||
new BasicAuthenticationBeanDefinitionParser(realm).parse(basicAuthElt, parserContext);
|
||||
}
|
||||
|
||||
Element formLoginElt = DomUtils.getChildElementByTagName(element, Elements.FORM_LOGIN);
|
||||
|
||||
if (formLoginElt != null || autoConfig) {
|
||||
FormLoginBeanDefinitionParser parser = new FormLoginBeanDefinitionParser("/j_spring_security_check",
|
||||
"org.springframework.security.ui.webapp.AuthenticationProcessingFilter");
|
||||
|
||||
parser.parse(formLoginElt, parserContext);
|
||||
formLoginFilter = parser.getFilterBean();
|
||||
formLoginEntryPoint = parser.getEntryPointBean();
|
||||
formLoginPage = parser.getLoginPage();
|
||||
}
|
||||
|
||||
Element openIDLoginElt = DomUtils.getChildElementByTagName(element, Elements.OPENID_LOGIN);
|
||||
|
||||
if (openIDLoginElt != null) {
|
||||
FormLoginBeanDefinitionParser parser = new FormLoginBeanDefinitionParser("/j_spring_openid_security_check",
|
||||
"org.springframework.security.ui.openid.OpenIDAuthenticationProcessingFilter");
|
||||
|
||||
parser.parse(openIDLoginElt, parserContext);
|
||||
openIDFilter = parser.getFilterBean();
|
||||
openIDEntryPoint = parser.getEntryPointBean();
|
||||
openIDLoginPage = parser.getLoginPage();
|
||||
}
|
||||
|
||||
if (formLoginFilter == null && openIDFilter == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (formLoginFilter != null) {
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.FORM_LOGIN_FILTER, formLoginFilter);
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.FORM_LOGIN_ENTRY_POINT, formLoginEntryPoint);
|
||||
}
|
||||
|
||||
if (openIDFilter != null) {
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_FILTER, openIDFilter);
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_ENTRY_POINT, openIDEntryPoint);
|
||||
}
|
||||
|
||||
// If no login page has been defined, add in the default page generator.
|
||||
if (formLoginPage == null && openIDLoginPage == null) {
|
||||
logger.info("No login page configured. The default internal one will be used. Use the '"
|
||||
+ FormLoginBeanDefinitionParser.ATT_LOGIN_PAGE + "' attribute to set the URL of the login page.");
|
||||
BeanDefinitionBuilder loginPageFilter =
|
||||
BeanDefinitionBuilder.rootBeanDefinition(DefaultLoginPageGeneratingFilter.class);
|
||||
|
||||
if (formLoginFilter != null) {
|
||||
loginPageFilter.addConstructorArg(new RuntimeBeanReference(BeanIds.FORM_LOGIN_FILTER));
|
||||
}
|
||||
|
||||
if (openIDFilter != null) {
|
||||
loginPageFilter.addConstructorArg(new RuntimeBeanReference(BeanIds.OPEN_ID_FILTER));
|
||||
}
|
||||
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.DEFAULT_LOGIN_PAGE_GENERATING_FILTER,
|
||||
loginPageFilter.getBeanDefinition());
|
||||
}
|
||||
|
||||
// We need to establish the main entry point.
|
||||
// Basic takes precedence if explicit element is used and no others are configured
|
||||
if (basicAuthElt != null && formLoginElt == null && openIDLoginElt == null) {
|
||||
parserContext.getRegistry().registerAlias(BeanIds.BASIC_AUTHENTICATION_ENTRY_POINT, BeanIds.MAIN_ENTRY_POINT);
|
||||
return;
|
||||
}
|
||||
|
||||
// If formLogin has been enabled either through an element or auto-config, then it is used if no openID login page
|
||||
// has been set
|
||||
if (formLoginFilter != null && openIDLoginPage == null) {
|
||||
parserContext.getRegistry().registerAlias(BeanIds.FORM_LOGIN_ENTRY_POINT, BeanIds.MAIN_ENTRY_POINT);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise use OpenID
|
||||
if (openIDFilter != null && formLoginFilter == null) {
|
||||
parserContext.getRegistry().registerAlias(BeanIds.OPEN_ID_ENTRY_POINT, BeanIds.MAIN_ENTRY_POINT);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Couldn't set entry point");
|
||||
}
|
||||
|
||||
static UrlMatcher createUrlMatcher(Element element) {
|
||||
String patternType = element.getAttribute(ATT_PATH_TYPE);
|
||||
if (!StringUtils.hasText(patternType)) {
|
||||
|
|
|
@ -8,6 +8,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.security.AuthenticationException;
|
||||
import org.springframework.security.ui.AbstractProcessingFilter;
|
||||
import org.springframework.security.ui.FilterChainOrder;
|
||||
|
@ -26,21 +27,52 @@ import org.springframework.security.ui.rememberme.AbstractRememberMeServices;
|
|||
public class DefaultLoginPageGeneratingFilter extends SpringSecurityFilter {
|
||||
public static final String DEFAULT_LOGIN_PAGE_URL = "/spring_security_login";
|
||||
public static final String ERROR_PARAMETER_NAME = "login_error";
|
||||
boolean formLoginEnabled;
|
||||
boolean openIdEnabled;
|
||||
private String authenticationUrl;
|
||||
private String usernameParameter;
|
||||
private String passwordParameter;
|
||||
private String rememberMeParameter;
|
||||
|
||||
public DefaultLoginPageGeneratingFilter(AuthenticationProcessingFilter authFilter) {
|
||||
authenticationUrl = authFilter.getDefaultFilterProcessesUrl();
|
||||
usernameParameter = authFilter.getUsernameParameter();
|
||||
passwordParameter = authFilter.getPasswordParameter();
|
||||
|
||||
if (authFilter.getRememberMeServices() instanceof AbstractRememberMeServices) {
|
||||
rememberMeParameter = ((AbstractRememberMeServices)authFilter.getRememberMeServices()).getParameter();
|
||||
}
|
||||
private String openIDauthenticationUrl;
|
||||
private String openIDusernameParameter;
|
||||
private String openIDrememberMeParameter;
|
||||
|
||||
public DefaultLoginPageGeneratingFilter(AbstractProcessingFilter filter) {
|
||||
if (filter instanceof AuthenticationProcessingFilter) {
|
||||
init((AuthenticationProcessingFilter)filter, null);
|
||||
} else {
|
||||
init(null, filter);
|
||||
}
|
||||
}
|
||||
|
||||
public DefaultLoginPageGeneratingFilter(AuthenticationProcessingFilter authFilter, AbstractProcessingFilter openIDFilter) {
|
||||
init(authFilter, openIDFilter);
|
||||
}
|
||||
|
||||
private void init(AuthenticationProcessingFilter authFilter, AbstractProcessingFilter openIDFilter) {
|
||||
if (authFilter != null) {
|
||||
formLoginEnabled = true;
|
||||
authenticationUrl = authFilter.getDefaultFilterProcessesUrl();
|
||||
usernameParameter = authFilter.getUsernameParameter();
|
||||
passwordParameter = authFilter.getPasswordParameter();
|
||||
|
||||
if (authFilter.getRememberMeServices() instanceof AbstractRememberMeServices) {
|
||||
rememberMeParameter = ((AbstractRememberMeServices)authFilter.getRememberMeServices()).getParameter();
|
||||
}
|
||||
}
|
||||
|
||||
if (openIDFilter != null) {
|
||||
openIdEnabled = true;
|
||||
openIDauthenticationUrl = openIDFilter.getAuthenticationFailureUrl();
|
||||
openIDusernameParameter = (String) (new BeanWrapperImpl(openIDFilter)).getPropertyValue("claimedIdentityFieldName");
|
||||
|
||||
if (openIDFilter.getRememberMeServices() instanceof AbstractRememberMeServices) {
|
||||
openIDrememberMeParameter = ((AbstractRememberMeServices)openIDFilter.getRememberMeServices()).getParameter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
if (isLoginUrlRequest(request)) {
|
||||
response.getOutputStream().print(generateLoginPageHtml(request));
|
||||
|
@ -68,24 +100,59 @@ public class DefaultLoginPageGeneratingFilter extends SpringSecurityFilter {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "<html><head><title>Login Page</title></head><body onload='document.f.j_username.focus();'>\n" +
|
||||
(loginError ? ("<font color='red'>Your login attempt was not successful, try again.<br/><br/>Reason: " +
|
||||
errorMsg + "</font>") : "") +
|
||||
" <form name='f' action='" + request.getContextPath() + authenticationUrl + "' method='POST'>\n" +
|
||||
" <table>\n" +
|
||||
" <tr><td>User:</td><td><input type='text' name='" + usernameParameter + "' value='" + lastUser +
|
||||
"'></td></tr>\n" +
|
||||
" <tr><td>Password:</td><td><input type='password' name='"+ passwordParameter +"'></td></tr>\n" +
|
||||
|
||||
(rememberMeParameter == null ? "" :
|
||||
" <tr><td><input type='checkbox' name='"+ rememberMeParameter +
|
||||
"'></td><td>Remember me on this computer.</td></tr>\n"
|
||||
) +
|
||||
" <tr><td colspan='2'><input name=\"submit\" type=\"submit\"></td></tr>\n" +
|
||||
" <tr><td colspan='2'><input name=\"reset\" type=\"reset\"></td></tr>\n" +
|
||||
" </table>\n" +
|
||||
" </form></body></html>";
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
sb.append("<html><head><title>Login Page</title></head>");
|
||||
|
||||
if (formLoginEnabled) {
|
||||
sb.append("<body onload='document.f.").append(usernameParameter).append(".focus();'>\n");
|
||||
}
|
||||
|
||||
if (loginError) {
|
||||
sb.append("<p><font color='red'>Your login attempt was not successful, try again.<br/><br/>Reason: ");
|
||||
sb.append(errorMsg);
|
||||
sb.append("</font></p>");
|
||||
}
|
||||
|
||||
if (formLoginEnabled) {
|
||||
sb.append("<h3>Login with Username and Password</h3>");
|
||||
sb.append("<form name='f' action='").append(request.getContextPath()).append(authenticationUrl).append("' method='POST'>\n");
|
||||
sb.append(" <table>\n");
|
||||
sb.append(" <tr><td>User:</td><td><input type='text' name='");
|
||||
sb.append(usernameParameter).append("' value='").append(lastUser).append("'></td></tr>\n");
|
||||
sb.append(" <tr><td>Password:</td><td><input type='password' name='").append(passwordParameter).append("'/></td></tr>\n");
|
||||
|
||||
if (rememberMeParameter != null) {
|
||||
sb.append(" <tr><td><input type='checkbox' name='").append(rememberMeParameter).append("'/></td><td>Remember me on this computer.</td></tr>\n");
|
||||
}
|
||||
|
||||
sb.append(" <tr><td colspan='2'><input name=\"submit\" type=\"submit\"/></td></tr>\n");
|
||||
sb.append(" <tr><td colspan='2'><input name=\"reset\" type=\"reset\"/></td></tr>\n");
|
||||
sb.append(" </table>\n");
|
||||
sb.append("</form>");
|
||||
}
|
||||
|
||||
if(openIdEnabled) {
|
||||
sb.append("<h3>Login with OpenID Identity</h3>");
|
||||
sb.append("<form name='oidf' action='").append(request.getContextPath()).append(openIDauthenticationUrl).append("' method='POST'>\n");
|
||||
sb.append(" <table>\n");
|
||||
sb.append(" <tr><td>Identity:</td><td><input type='text' name='");
|
||||
sb.append(openIDusernameParameter).append("'/></td></tr>\n");
|
||||
|
||||
if (rememberMeParameter != null) {
|
||||
sb.append(" <tr><td><input type='checkbox' name='").append(openIDrememberMeParameter).append("'></td><td>Remember me on this computer.</td></tr>\n");
|
||||
}
|
||||
|
||||
sb.append(" <tr><td colspan='2'><input name=\"submit\" type=\"submit\"/></td></tr>\n");
|
||||
sb.append(" <tr><td colspan='2'><input name=\"reset\" type=\"reset\"/></td></tr>\n");
|
||||
sb.append(" </table>\n");
|
||||
sb.append("</form>");
|
||||
}
|
||||
|
||||
sb.append("</body></html>");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
|
|
|
@ -223,7 +223,7 @@ logout.attlist &=
|
|||
attribute invalidate-session {"true" | "false"}?
|
||||
|
||||
form-login =
|
||||
## Sets up a form login configuration
|
||||
## Sets up a form login configuration for authentication with a username and password
|
||||
element form-login {form-login.attlist, empty}
|
||||
form-login.attlist &=
|
||||
## The URL that the login form is posted to. If unspecified, it defaults to /j_spring_security_check.
|
||||
|
@ -238,6 +238,11 @@ form-login.attlist &=
|
|||
## The URL for the login failure page. If no login failure URL is specified, Spring Security will automatically create a failure login URL at /spring_security_login?login_error and a corresponding filter to render that login failure URL when requested.
|
||||
attribute authentication-failure-url {xsd:string}?
|
||||
|
||||
openid-login =
|
||||
## Sets up form login for authentication with an Open ID identity
|
||||
element openid-login {form-login.attlist, empty}
|
||||
|
||||
|
||||
filter-chain-map =
|
||||
## Used to explicitly configure a FilterChainProxy instance with a FilterChainMap
|
||||
element filter-chain-map {filter-chain-map.attlist, filter-chain+}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
targetNamespace="http://www.springframework.org/schema/security">
|
||||
|
||||
<xs:attributeGroup name="hash">
|
||||
|
||||
<xs:attribute name="hash" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Defines the hashing algorithm used on user passwords. We recommend
|
||||
|
@ -474,7 +475,8 @@
|
|||
</xs:element>
|
||||
<xs:element name="form-login">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Sets up a form login configuration</xs:documentation>
|
||||
<xs:documentation>Sets up a form login configuration for authentication with
|
||||
a username and password</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:attributeGroup ref="security:form-login.attlist"/>
|
||||
|
@ -743,6 +745,14 @@
|
|||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
<xs:element name="openid-login">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Sets up form login for authentication with an Open ID identity</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:attributeGroup ref="security:form-login.attlist"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="filter-chain-map">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Used to explicitly configure a FilterChainProxy instance with a
|
||||
|
|
Loading…
Reference in New Issue