@Override
protected HandlerResult authenticateUsernamePasswordInternal(final
UsernamePasswordCredential credentials, final String originalPassword)
throws GeneralSecurityException, PreventedException
{
try
{
if(validateCredentials(credentials.getUsername(),
credentials.getPassword(),
credentials.getPancard()))
{
final String username = credentials.getUsername();
HandlerResult result = createHandlerResult(credentials, this.
principalFactory.createPrincipal(username), null);
return result;
}
}
catch (final Exception e)
{
throw new FailedLoginException();
}
throw new FailedLoginException();
}
validateCredentials method takes all my parameters and validates the user.
On Wednesday, February 7, 2018 at 6:22:03 PM UTC+5:30, Jeffrey Ramsay wrote:
>
> :) Let us know how your custom authentication handler works out; I'm
> interesting in doing this the correct way, eventually.
>
> -Jeff
>
> On Wed, Feb 7, 2018 at 7:32 AM, Ramakrishna G <[email protected] <javascript:>>
> wrote:
>
>> Hey Jeffrey Ramsay, Thankyou so much. You have saved me!!
>>
>>
>> Ramakrishna G
>>
>> On Tue, Feb 6, 2018 at 6:18 PM, Jeffrey Ramsay <[email protected]
>> <javascript:>> wrote:
>>
>>> In addition to modding the login-webflow.xml form to add "database" as
>>> a required property, I modified UsernamePasswordCredential.java and
>>> AbstractUsernamePasswordAuthenticationHandler.java to get the value of the
>>> new form element; see highlighted.
>>>
>>> Also, I modified QueryDatabaseAuthenticationHandler.java to extend the
>>> SQL query with a new conditional for jdbc authentication:
>>>
>>> cas.authn.jdbc.query[0].sql=select * from cas_users where cas_user=? and
>>> cas_domain=?
>>>
>>> I'm now stuck trying to mod CasPersonDirectoryConfiguration.java to get
>>> attributes per user by domain/database
>>>
>>> cas.authn.attributeRepository.jdbc[0].sql=*select * from cas_attrs
>>> where {0}*
>>>
>>> I plan to rename database to domain as to not confuse anyone.
>>>
>>> file: UsernamePasswordCredential.java
>>>
>>> package org.apereo.cas.authentication;
>>>
>>> import org.apache.commons.lang3.builder.HashCodeBuilder;
>>>
>>> import javax.validation.constraints.Size;
>>> import java.io.Serializable;
>>>
>>> /**
>>> * Credential for authenticating with a username and password.
>>> *
>>> * @author Scott Battaglia
>>> * @author Marvin S. Addison
>>> * @since 3.0.0
>>> */
>>> public class UsernamePasswordCredential implements Credential,
>>> Serializable {
>>>
>>> /**
>>> * Authentication attribute name for password.
>>> **/
>>> public static final String AUTHENTICATION_ATTRIBUTE_PASSWORD =
>>> "credential";
>>> public static final String AUTHENTICATION_ATTRIBUTE_DATABASE =
>>> "credential";
>>>
>>> private static final long serialVersionUID = -700605081472810939L;
>>>
>>> @Size(min = 1, message = "required.username")
>>> private String username;
>>>
>>> @Size(min = 1, message = "required.password")
>>> private String password;
>>>
>>> private String database;
>>>
>>> /**
>>> * Default constructor.
>>> */
>>> public UsernamePasswordCredential() {
>>> }
>>>
>>> /**
>>> * Creates a new instance with the given username and password.
>>> *
>>> * @param userName Non-null user name.
>>> * @param password Non-null password.
>>> */
>>> public UsernamePasswordCredential(final String userName, final
>>> String password, final String database) {
>>> this.username = userName;
>>> this.password = password;
>>> this.database = database;
>>> }
>>>
>>> public String getPassword() {
>>> return this.password;
>>> }
>>>
>>> public void setPassword(final String password) {
>>> this.password = password;
>>> }
>>>
>>> public String getDatabase() {
>>> return this.database;
>>> }
>>>
>>> public void setDatabase(final String database) {
>>> this.database = database;
>>> }
>>>
>>> public String getUsername() {
>>> return this.username;
>>> }
>>>
>>> public void setUsername(final String userName) {
>>> this.username = userName;
>>> }
>>>
>>> @Override
>>> public String getId() {
>>> return this.username;
>>> }
>>>
>>> @Override
>>> public String toString() {
>>> return this.username;
>>> }
>>>
>>> @Override
>>> public boolean equals(final Object o) {
>>> if (this == o) {
>>> return true;
>>> }
>>> if (o == null || getClass() != o.getClass()) {
>>> return false;
>>> }
>>>
>>> final UsernamePasswordCredential that =
>>> (UsernamePasswordCredential) o;
>>>
>>> if (this.password != null ? !this.password.equals(that.password)
>>> : that.password != null) {
>>> return false;
>>> }
>>>
>>> if (this.database != null ? !this.database.equals(that.database)
>>> : that.database != null) {
>>> return false;
>>> }
>>>
>>> return this.username != null ?
>>> this.username.equals(that.username) : that.username == null;
>>> }
>>>
>>> @Override
>>> public int hashCode() {
>>> return new HashCodeBuilder()
>>> .append(this.username)
>>> .append(this.password)
>>> .append(this.database)
>>> .toHashCode();
>>> }
>>>
>>> }
>>>
>>> file: AbstractUsernamePasswordAuthenticationHandler.java
>>>
>>> package org.apereo.cas.authentication.handler.support;
>>>
>>> import org.apache.commons.lang3.StringUtils;
>>> import org.apereo.cas.authentication.Credential;
>>> import org.apereo.cas.authentication.HandlerResult;
>>> import org.apereo.cas.authentication.PreventedException;
>>> import org.apereo.cas.authentication.UsernamePasswordCredential;
>>> import org.apereo.cas.authentication.handler.PrincipalNameTransformer;
>>> import org.apereo.cas.authentication.principal.PrincipalFactory;
>>> import
>>> org.apereo.cas.authentication.support.password.PasswordPolicyConfiguration;
>>> import org.apereo.cas.services.ServicesManager;
>>> import org.slf4j.Logger;
>>> import org.slf4j.LoggerFactory;
>>> import org.springframework.security.crypto.password.NoOpPasswordEncoder;
>>> import org.springframework.security.crypto.password.PasswordEncoder;
>>>
>>> import javax.security.auth.login.AccountNotFoundException;
>>> import javax.security.auth.login.FailedLoginException;
>>> import java.security.GeneralSecurityException;
>>> import java.util.function.Predicate;
>>>
>>> /**
>>> * Abstract class to override supports so that we don't need to
>>> duplicate the
>>> * check for UsernamePasswordCredential.
>>> *
>>> * @author Scott Battaglia
>>> * @author Marvin S. Addison
>>> * @since 3.0.0
>>> */
>>> public abstract class AbstractUsernamePasswordAuthenticationHandler
>>> extends AbstractPreAndPostProcessingAuthenticationHandler {
>>> private static final Logger LOGGER =
>>> LoggerFactory.getLogger(AbstractUsernamePasswordAuthenticationHandler.class);
>>>
>>> private PasswordEncoder passwordEncoder =
>>> NoOpPasswordEncoder.getInstance();
>>>
>>> private PrincipalNameTransformer principalNameTransformer =
>>> formUserId -> formUserId;
>>>
>>> private Predicate<Credential> credentialSelectionPredicate =
>>> credential -> true;
>>>
>>> private PasswordPolicyConfiguration passwordPolicyConfiguration;
>>>
>>> public AbstractUsernamePasswordAuthenticationHandler(final String
>>> name, final ServicesManager servicesManager, final PrincipalFactory
>>> principalFactory,
>>> final Integer
>>> order) {
>>> super(name, servicesManager, principalFactory, order);
>>> }
>>>
>>> @Override
>>> protected HandlerResult doAuthentication(final Credential
>>> credential) throws GeneralSecurityException, PreventedException {
>>>
>>> final UsernamePasswordCredential originalUserPass =
>>> (UsernamePasswordCredential) credential;
>>> final UsernamePasswordCredential userPass = new
>>> UsernamePasswordCredential(originalUserPass.getUsername(),
>>>
>>> originalUserPass.getPassword(),
>>>
>>> originalUserPass.getDatabase());
>>>
>>> if (StringUtils.isBlank(userPass.getUsername())) {
>>> throw new AccountNotFoundException("Username is null.");
>>> }
>>>
>>> LOGGER.debug("Transforming credential username via [{}]",
>>> this.principalNameTransformer.getClass().getName());
>>> final String transformedUsername =
>>> this.principalNameTransformer.transform(userPass.getUsername());
>>> if (StringUtils.isBlank(transformedUsername)) {
>>> throw new AccountNotFoundException("Transformed username is
>>> null.");
>>> }
>>>
>>> if (StringUtils.isBlank(userPass.getPassword())) {
>>> throw new FailedLoginException("Password is null.");
>>> }
>>>
>>> LOGGER.debug("Attempting to encode credential password via [{}]
>>> for [{}]", this.passwordEncoder.getClass().getName(), transformedUsername);
>>> final String transformedPsw =
>>> this.passwordEncoder.encode(userPass.getPassword());
>>> if (StringUtils.isBlank(transformedPsw)) {
>>> throw new AccountNotFoundException("Encoded password is
>>> null.");
>>> }
>>>
>>> LOGGER.debug("JJR - myDatabase [{}]", userPass.getDatabase());
>>> if (StringUtils.isBlank(userPass.getDatabase())) {
>>> throw new AccountNotFoundException("Database is not set.");
>>> }
>>>
>>> userPass.setUsername(transformedUsername);
>>> userPass.setPassword(transformedPsw);
>>>
>>> LOGGER.debug("Attempting authentication internally for
>>> transformed credential [{}]", userPass);
>>> return authenticateUsernamePasswordInternal(userPass,
>>> originalUserPass.getPassword());
>>> }
>>>
>>>
>>> /**
>>> * Authenticates a username/password credential by an arbitrary
>>> strategy with extra parameter original credential password before
>>> * encoding password. Override it if implementation need to use
>>> original password for authentication.
>>> *
>>> * @param transformedCredential the credential object bearing the
>>> transformed username and password.
>>> * @param originalPassword original password from credential
>>> before password encoding
>>> * @return HandlerResult resolved from credential on authentication
>>> success or null if no principal could be resolved
>>> * from the credential.
>>> * @throws GeneralSecurityException On authentication failure.
>>> * @throws PreventedException On the indeterminate case when
>>> authentication is prevented.
>>> */
>>> protected abstract HandlerResult
>>> authenticateUsernamePasswordInternal(UsernamePasswordCredential
>>> transformedCredential, String originalPassword)
>>> throws GeneralSecurityException, PreventedException;
>>>
>>> protected PasswordPolicyConfiguration
>>> getPasswordPolicyConfiguration() {
>>> return this.passwordPolicyConfiguration;
>>> }
>>>
>>> public void setPasswordEncoder(final PasswordEncoder
>>> passwordEncoder) {
>>> this.passwordEncoder = passwordEncoder;
>>> }
>>>
>>> public void setCredentialSelectionPredicate(final
>>> Predicate<Credential> credentialSelectionPredicate) {
>>> this.credentialSelectionPredicate = credentialSelectionPredicate;
>>> }
>>>
>>> public void setPrincipalNameTransformer(final
>>> PrincipalNameTransformer principalNameTransformer) {
>>> this.principalNameTransformer = principalNameTransformer;
>>> }
>>>
>>> public void setPasswordPolicyConfiguration(final
>>> PasswordPolicyConfiguration passwordPolicyConfiguration) {
>>> this.passwordPolicyConfiguration = passwordPolicyConfiguration;
>>> }
>>>
>>> @Override
>>> public boolean supports(final Credential credential) {
>>> if (credential instanceof UsernamePasswordCredential) {
>>> if (this.credentialSelectionPredicate != null) {
>>> return
>>> this.credentialSelectionPredicate.test(credential);
>>> }
>>> return true;
>>> }
>>> return false;
>>> }
>>>
>>> /**
>>> * Used in case passwordEncoder is used to match raw password with
>>> encoded password. Mainly for BCRYPT password encoders where each encoded
>>> * password is different and we cannot use traditional compare of
>>> encoded strings to check if passwords match
>>> *
>>> * @param charSequence raw not encoded password
>>> * @param password encoded password to compare with
>>> * @return true in case charSequence matched encoded password
>>> */
>>> protected boolean matches(final CharSequence charSequence, final
>>> String password) {
>>> return this.passwordEncoder.matches(charSequence, password);
>>> }
>>> }
>>>
>>> file: QueryDatabaseAuthenticationHandler.java
>>>
>>> package org.apereo.cas.adaptors.jdbc;
>>>
>>> import org.apache.commons.lang3.BooleanUtils;
>>> import org.apache.commons.lang3.StringUtils;
>>> import org.apereo.cas.authentication.HandlerResult;
>>> import org.apereo.cas.authentication.PreventedException;
>>> import org.apereo.cas.authentication.UsernamePasswordCredential;
>>> import org.apereo.cas.authentication.exceptions.AccountDisabledException;
>>> import
>>> org.apereo.cas.authentication.exceptions.AccountPasswordMustChangeException;
>>> import org.apereo.cas.authentication.principal.PrincipalFactory;
>>> import org.apereo.cas.services.ServicesManager;
>>> import org.slf4j.Logger;
>>> import org.slf4j.LoggerFactory;
>>> import org.springframework.dao.DataAccessException;
>>> import org.springframework.dao.IncorrectResultSizeDataAccessException;
>>>
>>> import javax.security.auth.login.AccountNotFoundException;
>>> import javax.security.auth.login.FailedLoginException;
>>> import javax.sql.DataSource;
>>> import java.security.GeneralSecurityException;
>>> import java.util.Collections;
>>> import java.util.LinkedHashMap;
>>> import java.util.Map;
>>>
>>> /**
>>> * Class that if provided a query that returns a password (parameter of
>>> query
>>> * must be username) will compare that password to a translated version
>>> of the
>>> * password provided by the user. If they match, then authentication
>>> succeeds.
>>> * Default password translator is plaintext translator.
>>> *
>>> * @author Scott Battaglia
>>> * @author Dmitriy Kopylenko
>>> * @author Marvin S. Addison
>>> * @since 3.0.0
>>> */
>>> public class QueryDatabaseAuthenticationHandler extends
>>> AbstractJdbcUsernamePasswordAuthenticationHandler {
>>>
>>> private static final Logger LOGGER =
>>> LoggerFactory.getLogger(QueryDatabaseAuthenticationHandler.class);
>>>
>>> private final String sql;
>>> private final String fieldPassword;
>>> private final String fieldExpired;
>>> private final String fieldDisabled;
>>> private Map<String, String> principalAttributeMap =
>>> Collections.emptyMap();
>>>
>>> public QueryDatabaseAuthenticationHandler(final String name, final
>>> ServicesManager servicesManager,
>>> final PrincipalFactory
>>> principalFactory,
>>> final Integer order, final
>>> DataSource dataSource, final String sql,
>>> final String
>>> fieldPassword, final String fieldExpired, final String fieldDisabled,
>>> final Map<String, String>
>>> attributes) {
>>> super(name, servicesManager, principalFactory, order,
>>> dataSource);
>>> this.sql = sql;
>>> this.fieldPassword = fieldPassword;
>>> this.fieldExpired = fieldExpired;
>>> this.fieldDisabled = fieldDisabled;
>>> this.principalAttributeMap = attributes;
>>> }
>>>
>>> @Override
>>> protected HandlerResult authenticateUsernamePasswordInternal(final
>>> UsernamePasswordCredential credential, final String originalPassword)
>>> throws GeneralSecurityException, PreventedException {
>>>
>>> if (StringUtils.isBlank(this.sql) || getJdbcTemplate() == null) {
>>> throw new GeneralSecurityException("Authentication handler
>>> is not configured correctly. "
>>> + "No SQL statement or JDBC template is found.");
>>> }
>>>
>>> final Map<String, Object> attributes = new
>>> LinkedHashMap<>(this.principalAttributeMap.size());
>>> final String username = credential.getUsername();
>>> final String password = credential.getPassword();
>>> final String database = credential.getDatabase();
>>> try {
>>> LOGGER.debug("JJR - JDBC: username: [{}]", username);
>>> LOGGER.debug("JJR - JDBC: database: [{}]", database);
>>> LOGGER.debug("JJR - JDBC: this.sql: [{}]", this.sql);
>>> final Map<String, Object> dbFields =
>>> getJdbcTemplate().queryForMap(this.sql, username, database);
>>> final String dbPassword = (String)
>>> dbFields.get(this.fieldPassword);
>>>
>>> if (StringUtils.isNotBlank(originalPassword) &&
>>> !matches(originalPassword, dbPassword)
>>> || StringUtils.isBlank(originalPassword) &&
>>> !StringUtils.equals(password, dbPassword)) {
>>> throw new FailedLoginException("Password does not match
>>> value on record.");
>>> }
>>> if (StringUtils.isNotBlank(this.fieldDisabled)) {
>>> final Object dbDisabled =
>>> dbFields.get(this.fieldDisabled);
>>> if (dbDisabled != null &&
>>> (Boolean.TRUE.equals(BooleanUtils.toBoolean(dbDisabled.toString())) ||
>>> dbDisabled.equals(Integer.valueOf(1)))) {
>>> throw new AccountDisabledException("Account has been
>>> disabled");
>>> }
>>> }
>>> if (StringUtils.isNotBlank(this.fieldExpired)) {
>>> final Object dbExpired = dbFields.get(this.fieldExpired);
>>> if (dbExpired != null &&
>>> (Boolean.TRUE.equals(BooleanUtils.toBoolean(dbExpired.toString())) ||
>>> dbExpired.equals(Integer.valueOf(1)))) {
>>> throw new
>>> AccountPasswordMustChangeException("Password has expired");
>>> }
>>> }
>>>
>>> this.principalAttributeMap.entrySet().forEach(a -> {
>>> final Object attribute = dbFields.get(a.getKey());
>>> if (attribute != null) {
>>> LOGGER.debug("Found attribute [{}] from the query
>>> results", a);
>>> final String principalAttrName = a.getValue();
>>> attributes.put(principalAttrName,
>>> attribute.toString());
>>> } else {
>>> LOGGER.warn("Requested attribute [{}] could not be
>>> found in the query results", a.getKey());
>>> }
>>>
>>> });
>>>
>>> } catch (final IncorrectResultSizeDataAccessException e) {
>>> if (e.getActualSize() == 0) {
>>> throw new AccountNotFoundException(username + " not
>>> found with SQL query");
>>> }
>>> throw new FailedLoginException("Multiple records found for "
>>> + username);
>>> } catch (final DataAccessException e) {
>>> throw new PreventedException("SQL exception while executing
>>> query for " + username, e);
>>> }
>>> return createHandlerResult(credential,
>>> this.principalFactory.createPrincipal(username, attributes), null);
>>> }
>>> }
>>>
>>> -Jeff
>>>
>>> On Tue, Feb 6, 2018 at 12:32 AM, Ramakrishna G <[email protected]
>>> <javascript:>> wrote:
>>>
>>>> Perfect Jeffrey Ramsay. Thankyou so much.
>>>>
>>>>
>>>> How did you get the value into your custom authentication handler? Can
>>>> you pls guide me in that as well.
>>>>
>>>> On Mon, Feb 5, 2018 at 10:06 PM, Jeffrey Ramsay <[email protected]
>>>> <javascript:>> wrote:
>>>>
>>>>> Looks like we're trying to accomplish similar things. I updated my
>>>>> login form using the following with no errors.
>>>>>
>>>>> <section class="row">
>>>>> <label for="database">Database:</label>
>>>>> <div>
>>>>> <select class="required" id="database" name="database"
>>>>> tabindex="3" accesskey="d">
>>>>> <option value="conv">CONV</option>
>>>>> <option value="devl">DEVL</option>
>>>>> </select>
>>>>> </div>
>>>>> </section>
>>>>>
>>>>> -Jeff
>>>>>
>>>>> On Mon, Feb 5, 2018 at 3:54 AM, Ramakrishna G <[email protected]
>>>>> <javascript:>> wrote:
>>>>>
>>>>>> I also changed the loginform.html to add the new filed but when I run
>>>>>> it says these error.
>>>>>>
>>>>>> 2018-02-05 14:18:25,742 ERROR [org.thymeleaf.TemplateEngine] -
>>>>>> <[THYMELEAF][http-nio-9443-exec-1] Exception processing template
>>>>>> "casLoginView": Error during execution of processor
>>>>>> 'org.thymeleaf.spring4.processor.SpringInputGeneralFieldTagProcessor'
>>>>>> (template: "fragments/loginform" - line 53, col 24)>
>>>>>>
>>>>>> org.thymeleaf.exceptions.TemplateProcessingException: Error during
>>>>>> execution of processor
>>>>>> 'org.thymeleaf.spring4.processor.SpringInputGeneralFieldTagProcessor'
>>>>>> (template: "fragments/loginform" - line 53, col 24)
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:117)
>>>>>>
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95)
>>>>>>
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633)
>>>>>>
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.engine.ProcessorTemplateHandler.handleStandaloneElement(ProcessorTemplateHandler.java:918)
>>>>>>
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.engine.StandaloneElementTag.beHandled(StandaloneElementTag.java:228)
>>>>>>
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at org.thymeleaf.engine.Model.process(Model.java:282)
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.engine.ProcessorTemplateHandler.handleStandaloneElement(ProcessorTemplateHandler.java:1204)
>>>>>>
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.engine.StandaloneElementTag.beHandled(StandaloneElementTag.java:228)
>>>>>>
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at org.thymeleaf.engine.Model.process(Model.java:282)
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1587)
>>>>>>
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.engine.OpenElementTag.beHandled(OpenElementTag.java:205)
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at org.thymeleaf.engine.Model.process(Model.java:282)
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1587)
>>>>>>
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.engine.OpenElementTag.beHandled(OpenElementTag.java:205)
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at org.thymeleaf.engine.Model.process(Model.java:282)
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at org.thymeleaf.engine.Model.process(Model.java:290)
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.engine.GatheringModelProcessable.process(GatheringModelProcessable.java:78)
>>>>>>
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.engine.ProcessorTemplateHandler.handleCloseElement(ProcessorTemplateHandler.java:1640)
>>>>>>
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.engine.CloseElementTag.beHandled(CloseElementTag.java:139)
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at org.thymeleaf.engine.TemplateModel.process(TemplateModel.java:136)
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:661)
>>>>>>
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
>>>>>> ~[thymeleaf-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.spring4.view.ThymeleafView.renderFragment(ThymeleafView.java:353)
>>>>>>
>>>>>> ~[thymeleaf-spring4-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.thymeleaf.spring4.view.ThymeleafView.render(ThymeleafView.java:191)
>>>>>> ~[thymeleaf-spring4-3.0.7.RELEASE.jar!/:3.0.7.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.mvc.servlet.ServletMvcView.doRender(ServletMvcView.java:55)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.mvc.view.AbstractMvcView.render(AbstractMvcView.java:204)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.ViewState.render(ViewState.java:293)
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.ViewState.doEnter(ViewState.java:185)
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at org.springframework.webflow.engine.State.enter(State.java:194)
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.Transition.execute(Transition.java:228)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:105)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at org.springframework.webflow.engine.State.enter(State.java:194)
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.Transition.execute(Transition.java:228)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:105)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at org.springframework.webflow.engine.State.enter(State.java:194)
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.Transition.execute(Transition.java:228)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.DecisionState.doEnter(DecisionState.java:51)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at org.springframework.webflow.engine.State.enter(State.java:194)
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.Transition.execute(Transition.java:228)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> at
>>>>>> org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
>>>>>>
>>>>>> ~[spring-webflow-2.4.6.RELEASE.jar!/:2.4.6.RELEASE]
>>>>>>
>>>>>> ...
>>>
>>> [Message clipped]
>>
>>
>> --
>> - Website: https://apereo.github.io/cas
>> - Gitter Chatroom: https://gitter.im/apereo/cas
>> - List Guidelines: https://goo.gl/1VRrw7
>> - Contributions: https://goo.gl/mh7qDG
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "CAS Community" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected] <javascript:>.
>> To view this discussion on the web visit
>> https://groups.google.com/a/apereo.org/d/msgid/cas-user/CAGST5P_gOAHj7o0SaAdVifcBJY4-mNEkGuxUE352JVZEkGeavA%40mail.gmail.com
>>
>> <https://groups.google.com/a/apereo.org/d/msgid/cas-user/CAGST5P_gOAHj7o0SaAdVifcBJY4-mNEkGuxUE352JVZEkGeavA%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
>
>
--
- Website: https://apereo.github.io/cas
- Gitter Chatroom: https://gitter.im/apereo/cas
- List Guidelines: https://goo.gl/1VRrw7
- Contributions: https://goo.gl/mh7qDG
---
You received this message because you are subscribed to the Google Groups "CAS
Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/a/apereo.org/d/msgid/cas-user/8b797e60-53d9-4b16-8517-ce0001947f02%40apereo.org.