Database-based authentication CasServer has implemented several JDBC-based AuthenticationHandler implementations for us, but they are not included in the core package of CasServer, it is included in cas-server-support-jdbc. If we want to use the JDBC-based AuthenticationHandler implemented by CasServer, we must
Database-based authentication Cas Server has implemented several JDBC-based AuthenticationHandler implementations for us, but they are not included in the core package of Cas Server, it is included in cas-server-support-jdbc. If we want to use the JDBC-based AuthenticationHandler implemented by Cas Server, we must
Database-based authentication
Cas Server itself has implemented several JDBC-based AuthenticationHandler implementations for us, but they are not included in the core package of Cas Server, but in cas-server-support-jdbc, if we want to use the JDBC-based AuthenticationHandler implemented by Cas Server, we must first drive the jar package corresponding to cas-server-support-jdbc and the relevant database, and the required data source implementation and other jar packages are added to the class path of Cas Server. If the configuration file of the Cas Server is modified based on the Maven war overwriting mechanism, you can add the following items in the dependencies of your Maven project (the corresponding driver is not attached ).
Org. jasig. cas
Cas-server-support-jdbc
$ {Cas. version}
Runtime
Cas Server has implemented three AuthenticationHandler Based on JDBC by default. They all inherit from AbstractJdbcUsernamePasswordAuthenticationHandler and require a DataSource during authentication. Here is a brief introduction to them.
1.1 BindModeSearchDatabaseAuthenticationHandler
BindModeSearchDatabaseAuthenticationHandler tries to establish a connection from the configured DataSource with the input username and password. If the connection is successful, authentication is successful. Otherwise, authentication fails. The following is a major piece of code of BindModeSearchDatabaseAuthenticationHandler source code. Through this code, we can clearly see its logic:
Protected final booleanAuthenticateUsernamePasswordInternal (
FinalUsernamePasswordCredentials credentials)
ThrowsAuthenticationException {
FinalString username = credentials. getUsername ();
FinalString password = credentials. getPassword ();
Try{
FinalConnection c =This. GetDataSource ()
. GetConnection (username, password );
DataSourceUtils.ReleaseConnection(C,This. GetDataSource ());
Returntrue;
}Catch(FinalSQLException e ){
Returnfalse;
}
}
Of course, this implementation also requires your DataSource to support getConnection (user, password). Otherwise, false is returned. Dbcp's BasicDataSource is not supported, while c3p0's ComboPooledDataSource is supported.
The following is an example of BindModeSearchDatabaseAuthenticationHandler Configuration:
"AuthenticationManager"
Class ="Org. jasig. cas. authentication. AuthenticationManagerImpl">
...
"AuthenticationHandlers">
...
"Org. jasig. cas. adaptors. jdbc. BindModeSearchDatabaseAuthenticationHandler">
"DataSource"Ref = "DataSource"/>
...
...
1.2 QueryDatabaseAuthenticationHandler
To use QueryDatabaseAuthenticationHandler, You need to specify an SQL statement. This SQL statement will receive a user name as the query condition and return the corresponding password. The SQL statement is used by QueryDatabaseAuthenticationHandler to query the corresponding password by the input user name. If yes, the query Password Matches the queried password. The matching result is used as the authentication result. If the user name does not exist, false is returned.
The following is the main code of QueryDatabaseAuthenticationHandler:
Protected final booleanAuthenticateUsernamePasswordInternal (FinalUsernamePasswordCredentials credentials)ThrowsAuthenticationException {
FinalString username = getPrincipalNameTransformer (). transform (credentials. getUsername ());
FinalString password = credentials. getPassword ();
FinalString encryptedPassword =This. GetPasswordEncoder (). encode (
Password );
Try{
FinalString dbPassword = getJdbcTemplate (). queryForObject (This. SQL, String.Class, Username );
ReturnDbPassword. equals (encryptedPassword );
}Catch(FinalIncorrectResultSizeDataAccessException e ){
// This means the username was not found.
Returnfalse;
}
}
The above logic is very obvious. As you can see, the username used by QueryDatabaseAuthenticationHandler is converted by PrincipalNameTransformer, And the password is encoded by PasswordEncoder. The PrincipalNameTransformer used in the JDBC AuthenticationHandler implementation in Cas Server is NoOpPrincipalNameTransformer without any conversion by default, and the PasswordEncoder used by default is PlainTextPasswordEncoder without any encoding. Of course, cas-server-jdbc-support also has two other types of support, namely PrefixSuffixPrincipalNameTransformer and DefaultPasswordEncoder.
1.2.1 PrefixSuffixPrincipalNameTransformer
PrefixSuffixPrincipalNameTransformer has obvious functions. As described by the name, it adds the specified prefix and suffix to the user name during conversion. Therefore, you must specify the prefix and suffix attributes when using them. The default value is null.
1.2.2 defapasspasswordencoder
The bottom layer of DefaultPasswordEncoder uses MessageDigest in the standard Java class library for encryption. It supports MD5, SHA, and other encryption algorithms. During use, you must specify the encryption algorithm by constructing the parameter encodingAlgorithm. You can use characterEncoding attribute injection to specify the encoding used for obtaining bytes. If this parameter is not specified, the default encoding is used. The following is the source code of defapasspasswordencoder, which shows the encryption logic of defapasspasswordencoder.
Public final classDefaultPasswordEncoderImplementsPasswordEncoder {
Privatestaticfinalchar[]HEX_DIGITS= {'0', '1', '2', '3', '4', '5', '6', '7', '8 ', '9', 'A', 'B', 'C', 'D', 'E', 'F '};
@ NotNull
PrivatefinalString encodingAlgorithm;
PrivateString characterEncoding;
PublicDefaultPasswordEncoder (FinalString encodingAlgorithm ){
This. EncodingAlgorithm = encodingAlgorithm;
}
PublicString encode (FinalString password ){
If(Password =Null){
Returnnull;
}
Try{
MessageDigest messageDigest = MessageDigest
.GetInstance(This. EncodingAlgorithm );
If(StringUtils.HasText(This. CharacterEncoding )){
MessageDigest. update (password. getBytes (This. CharacterEncoding ));
}Else{
MessageDigest. update (password. getBytes ());
}
Finalbyte[] Digest = messageDigest. digest ();
ReturnGetFormattedText (digest );
}Catch(FinalNoSuchAlgorithmException e ){
ThrownewSecurityException (e );
}Catch(FinalUnsupportedEncodingException e ){
ThrownewRuntimeException (e );
}
}
/**
* Takes the raw bytes from the digest and formats them correct.
*
*@ ParamBytes the raw bytes from the digest.
*@ ReturnThe formatted bytes.
*/
PrivateString getFormattedText (Byte[] Bytes ){
FinalStringBuilder buf =NewStringBuilder (bytes. length * 2 );
For(IntJ = 0; j <bytes. length; j ++ ){
Buf. append (HEX_DIGITS[(Bytes [j]> 4) & 0x0f]);
Buf. append (HEX_DIGITS[Bytes [j] & 0x0f]);
}
ReturnBuf. toString ();
}
PublicfinalvoidSetCharacterEncoding (FinalString characterEncoding ){
This. CharacterEncoding = characterEncoding;
}
}
If defapasspasswordencoder is required for authentication, make sure that the encryption method of the password stored in the database is consistent with the encryption algorithm and logic of defapasspasswordencoder. If none of these meet your needs, you can implement your own PrincipalNameTransformer and PasswordEncoder.
The following is an example of using QueryDatabaseAuthenticationHandler for authentication and MD5 ultpasswordencoder for MD5 encryption:
"AuthenticationManager"
Class ="Org. jasig. cas. authentication. AuthenticationManagerImpl">
...
"AuthenticationHandlers">
...
"Org. jasig. cas. adaptors. jdbc. QueryDatabaseAuthenticationHandler">
"DataSource"Ref = "DataSource"/>
"PasswordEncoder"Ref = "PasswordEncoder"/>
"SQL"Value = "Select password from t_user where username =? "/>
...
...
"PasswordEncoder"Class = "Org. jasig. cas. authentication. handler. DefaultPasswordEncoder">
"MD5"/>
1.3 SearchModeSearchDatabaseAuthenticationHandler
The main logic of SearchModeSearchDatabaseAuthenticationHandler is to query the input user name and password from the specified table as conditions. If the corresponding record exists, the authentication is successful. When using the AuthenticationHandler, We need to specify the table name (tableUsers), the field name (fieldUser) corresponding to the user name (fieldPassword) used for the query, and the field name (fieldPassword) corresponding to the password ). In addition, PrincipalNameTransformer and PasswordEncoder can be used selectively. The following is a major piece of code in the source code of SearchModeSearchDatabaseAuthenticationHandler:
Private static finalStringSQL _PREFIX= "Select count ('x') from ";
@ NotNull
PrivateString fieldUser;
@ NotNull
PrivateString fieldPassword;
@ NotNull
PrivateString tableUsers;
PrivateString SQL;
ProtectedfinalbooleanAuthenticateUsernamePasswordInternal (FinalUsernamePasswordCredentials credentials)ThrowsAuthenticationException {
FinalString transformedUsername = getPrincipalNameTransformer (). transform (credentials. getUsername ());
FinalString encytedpassword = getPasswordEncoder (). encode (credentials. getPassword ());
FinalintCount = getJdbcTemplate (). queryForInt (This. SQL,
TransformedUsername, encytedpassword );
ReturnCount> 0;
}
PublicvoidAfterPropertiesSet ()ThrowsException {
This. SQL =SQL _PREFIX+This. TableUsers + "Where" +This. FieldUser
+ "=? And "+This. FieldPassword + "=? ";
}
The following is a configuration example using SearchModeSearchDatabaseAuthenticationHandler:
"AuthenticationManager"
Class ="Org. jasig. cas. authentication. AuthenticationManagerImpl">
...
"AuthenticationHandlers">
...
"Org. jasig. cas. adaptors. jdbc. SearchModeSearchDatabaseAuthenticationHandler">
"DataSource"Ref = "DataSource"/>
"PasswordEncoder"Ref = "PasswordEncoder"/>
"TableUsers"Value = "T_user"/>
"FieldUser"Value = "Username"/>
"FieldPassword"Value = "Password"/>
...
...
So far, the three AuthenticationHandler that supports jdbc in cas-server-support-JDBC is finished. If you think they cannot meet your requirements, you can also use your own AuthenticationHandler. For other authentication methods, see the official documentation.
(Note: This article is based on cas 3.5.2)
Http://blog.csdn.net/elim168/article/details/44420293)