在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的內容,用此類替換原有的類便可