Cas (06) database-based authentication

Source: Internet
Author: User
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)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.