cas 自定義參數及驗證(10)

在cas-server 原始項目中,只提供了用戶名及密碼的驗證
綁定的參數在login-webflow.xml以下:java

<view-state id="viewLoginForm" view="casLoginView" model="credential">
        <binder>
            <binding property="username" /> 
            <binding property="password" />
        </binder>
        <on-entry>
            <set name="viewScope.commandName" value="'credential'" />
        </on-entry>
		<transition on="submit" bind="true" validate="true" to="realSubmit">
            <evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credential)" />
        </transition>
	</view-state>

驗證類以下:org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandlerweb

需求: 對於用戶的驗證,可能咱們不止只有username及password這兩個。而驗證的邏輯也可能很複雜。spring

此時就想綁定多個參數,及有本身的驗證類。sql

實現express

1.參數的獲取與綁定ide

 參數的綁定在login-webflow.xml 中,如咱們想綁定一個用戶類型的參數usertype測試

<view-state id="viewLoginForm" view="casLoginView" model="credential">
        <binder>
            <binding property="username" /> 
            <binding property="password" />
            <binding property="usertype"/>
            <!-- 綁定更多的參數 -->
        </binder>
        <on-entry>
            <set name="viewScope.commandName" value="'credential'" />
        </on-entry>
		<transition on="submit" bind="true" validate="true" to="realSubmit">
            <evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credential)" />
        </transition>
	</view-state>

  最後參數會封裝到一個叫org.jasig.cas.authentication.Credential 的類中,原項目中爲org.jasig.cas.authentication.UsernamePasswordCredentialthis

   這裏咱們要定義本身Credential的以下:lua

import org.jasig.cas.authentication.UsernamePasswordCredential;

public class MyCredential extends UsernamePasswordCredential {
    private static final long serialVersionUID = -7786406837239789068L;
    
    private String usertype; //用戶類型

    public String getUsertype() {
        return usertype;
    }
    public void setUsertype(String usertype) {
        this.usertype = usertype;
    }
   
}

修改login-webflow.xml 以下:code

<var name="credential" class="com.silver.cas.param.MyCredential" />

這樣參數usertype就會自動封裝致該類中了

2. 自定義驗證邏輯

 建立本身的驗證類如:

import java.security.GeneralSecurityException;

import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.login.FailedLoginException;
import javax.validation.constraints.NotNull;

import org.jasig.cas.adaptors.jdbc.AbstractJdbcUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.HandlerResult;
import org.jasig.cas.authentication.PreventedException;
import org.jasig.cas.authentication.UsernamePasswordCredential;
import org.jasig.cas.authentication.principal.SimplePrincipal;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;

public class MyAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {

    @NotNull
    private String sql;

    /** {@inheritDoc} */
    @Override
    protected final HandlerResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential credential)
            throws GeneralSecurityException, PreventedException {
        
        MyCredential myCredential = null;
        if(MyCredential.class.isInstance(credential)){
            myCredential = (MyCredential) credential;
        }else{
            throw new IllegalAccessError("驗證參數不匹配");
        }
        
        final String username = myCredential.getUsername();
        final String encryptedPassword = this.getPasswordEncoder().encode(myCredential.getPassword());
        try {
            final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username);
            if (!dbPassword.equals(encryptedPassword)) {
                throw new FailedLoginException("Password does not match value on record.");
            }
        } catch (final IncorrectResultSizeDataAccessException e) {
            if (e.getActualSize() == 0) {
                throw new AccountNotFoundException(username + " not found with SQL query");
            } else {
                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(myCredential, new SimplePrincipal(username), null);
    }

    /**
     * @param sql The sql to set.
     */
    public void setSql(final String sql) {
        this.sql = sql;
    }

}

  爲了測試方便,複製了原有的驗證邏輯。但能夠看到,此時的UsernamePasswordCredential 參數其實是咱們本身定義的Credential

  修改deployerConfigContext.xml,中authenticationManager bean的內容,用此類替換原有的類便可

相關文章
相關標籤/搜索