在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的内容,用此类替换原有的类便可