Hi, 

I made some customization on the login flow, see all login related 
code/configuration below.  

I read this in CAS 5.3.X documentation:  If “service” was specified to 
*/login*, “service” MUST also be a parameter of the form, containing the 
value originally passed to */login*. 

Is this saying the Form in casLoginView.html should have "service" 
parameter, along with username & password?  With the sample overlay 
project, I did not see "service" parameter in the form, but this works 
fine, i.e., if credential is incorrect, it keeps "service" parameter. 

This is my complete login webflow. 

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
      xmlns="http://www.springframework.org/schema/webflow";
      xsi:schemaLocation="http://www.springframework.org/schema/webflow
                          
http://www.springframework.org/schema/webflow/spring-webflow.xsd";>

    <action-state id="initializeLoginForm">
        <evaluate expression="initializeLoginAction" />
        <transition on="success" to="viewLoginForm"/>
    </action-state>

    <view-state id="viewLoginForm" view="casLoginView" model="credential">
        <binder>
            <binding property="username" required="true"/>
            <binding property="password" required="true"/>
        </binder>
        <transition on="submit" bind="true" validate="true" to="realSubmit" 
history="invalidate"/>
        <transition on="forgotPassword" to="forgotPwdSubFlow"/>
    </view-state>

    <action-state id="realSubmit">
        <evaluate expression="authenticationViaFormAction"/>
        <transition on="warn" to="warn"/>
        <transition on="success" to="checkLoginUser"/>
        <transition on="successWithWarnings" 
to="showAuthenticationWarningMessages"/>
        <transition on="authenticationFailure" 
to="handleAuthenticationFailure"/>
        <transition on="error" to="initializeLoginForm"/>
    </action-state>
  <action-state id="checkLoginUser">
      <evaluate expression="flowScope.forgotPasswordFlow=false" />
      <evaluate expression="checkLoginUserAction" />
      <transition on="changeLoginUserPassword" to="casMustChangePassView" />
      <transition on="setupEmail" to="confirmEmailAddress" />
      <transition on="success" to="createTicketGrantingTicket" />
      <transition on="error" to="initializeLoginForm" />
  </action-state>
  <view-state id="confirmEmailAddress" view="casConfirmEmailAddressView" 
model="emailAddressValue">
      <binder>
            <binding property="emailAddress" />
            <binding property="confirmEmailAddress" />
        </binder>
<transition on="submit" bind="true" validate="true" to="realChangeEmail"/>
    </view-state>   
    
  <action-state id="realChangeEmail">
        <evaluate expression="confirmEmailAddressAction" />
<transition on="success" to="createTicketGrantingTicket" />
<transition on="error" to="confirmEmailAddress" />
</action-state>
</flow>


package org.apereo.cas.config;

import javax.sql.DataSource;

import org.apereo.cas.adaptors.jdbc.QuestAuthenticationHandler;
import org.apereo.cas.authentication.AuthenticationEventExecutionPlan;
import 
org.apereo.cas.authentication.AuthenticationEventExecutionPlanConfigurer;
import org.apereo.cas.authentication.AuthenticationHandler;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.services.ServicesManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import 
org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import 
org.springframework.transaction.annotation.EnableTransactionManagement;

import com.quest.hub.cas.entity.UserRepository;

@Configuration("QuestAuthenticationEventExecutionPlanConfiguration")
@AutoConfigureAfter(QuestDatabaseConfiguration.class)
@EnableConfigurationProperties(CasConfigurationProperties.class)
@EnableTransactionManagement(proxyTargetClass = true)
public class QuestAuthenticationEventExecutionPlanConfiguration implements 
AuthenticationEventExecutionPlanConfigurer {
private static final Logger logger = 
LoggerFactory.getLogger(QuestAuthenticationEventExecutionPlanConfiguration.class);
    @Autowired
    private CasConfigurationProperties casProperties;
    
    @Autowired
    @Qualifier("servicesManager")
    private ServicesManager servicesManager;
    
    @Autowired
    @Qualifier("casDataSource")
    DataSource dataSource;
    
    @Autowired
    private UserRepository userRepository;    
    
    @Bean
    public AuthenticationHandler questAuthenticationHandler() {
        final QuestAuthenticationHandler handler = new 
QuestAuthenticationHandler("questAuthHandler", 
        servicesManager, null, 0, dataSource, userRepository);
        return handler;
    }

    @Override
    public void configureAuthenticationExecutionPlan(final 
AuthenticationEventExecutionPlan plan){
        plan.registerAuthenticationHandler(questAuthenticationHandler());
    }
}


package org.apereo.cas.adaptors.jdbc;

import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.sql.DataSource;

import org.apache.commons.lang3.time.DateUtils;
import org.apereo.cas.authentication.AuthenticationHandlerExecutionResult;
import org.apereo.cas.authentication.BasicCredentialMetaData;
import 
org.apereo.cas.authentication.DefaultAuthenticationHandlerExecutionResult;
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.exceptions.AccountTemporaryLockedException;
import 
org.apereo.cas.authentication.exceptions.OneMoreAttemptLoginException;
import 
org.apereo.cas.authentication.exceptions.TwoMoreAttemptLoginException;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.services.ServicesManager;
import org.apereo.cas.util.PasswordDigest;
import org.springframework.dao.DataAccessException;

import com.quest.hub.cas.entity.User;
import com.quest.hub.cas.entity.UserRepository;

import lombok.extern.slf4j.Slf4j;


/**
 */
@Slf4j
public class QuestAuthenticationHandler extends 
AbstractJdbcUsernamePasswordAuthenticationHandler {

private UserRepository userRepo;
public QuestAuthenticationHandler(String name, ServicesManager 
servicesManager, PrincipalFactory principalFactory,
            Integer order, DataSource dataSource, UserRepository userRepo) {
        super(name, servicesManager, principalFactory, order, dataSource);
        this.userRepo = userRepo;
    }
    
    protected final AuthenticationHandlerExecutionResult 
authenticateUsernamePasswordInternal(final UsernamePasswordCredential 
credential, final String originalPassword)
            throws GeneralSecurityException {
    try {
    User user = 
userRepo.findByLoginNameIgnoreCase(credential.getUsername());
validateUser(user);
if (!user.isEmployee()) {
return authenticateNonEmployee(credential, user);
} else {
throw new FailedLoginException("Login failed: do not support employee login 
yet."); 
}
    } catch (DataAccessException ex) {
     LOGGER.error("Looking up user error: " + credential.getUsername(), ex);
    throw new FailedLoginException("Login failed: cannot find user");
    }
    }


org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  org.apereo.cas.config.QuestAuthenticationEventExecutionPlanConfiguration,\
  org.apereo.cas.config.EmbeddedTomcatDatabaseConfiguration,\
  org.apereo.cas.config.QuestDatabaseConfiguration,\
  org.apereo.cas.config.EnvironmentConfig,\
  org.apereo.cas.config.CollaborationConfiguration,\
  org.apereo.cas.config.pm.JdbcPasswordManagementConfiguration,\
  org.apereo.cas.web.config.QuestCasSupportActionsConfiguration

Thx!


On Wednesday, February 6, 2019 at 1:35:57 PM UTC-5, rbon wrote:
>
> Yan,
>
> Can you post your code?
>
> Ray
>
> On Wed, 2019-02-06 at 10:00 -0800, Yan Zhou wrote:
>
> Hi there, 
>
> I extended CAS 5.3.4.  The app. redirects to CAS login page with service 
> parameter.
>
> When I type incorrect credential, I saw the invalid credential message, 
> but I lost service parameter, the screen refreshes to have only the CAS url.
>
> What could be missing in my code?
>
> Thx!
>
> -- 
> Ray Bon
> Programmer analyst
> Development Services, University Systems
> 2507218831 | CLE 019 | rb...@uvic.ca <javascript:>
>
>

-- 
- 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 cas-user+unsubscr...@apereo.org.
To view this discussion on the web visit 
https://groups.google.com/a/apereo.org/d/msgid/cas-user/df650307-43c9-421c-be67-46ad4cad60aa%40apereo.org.

Reply via email to