CAS server从网上直接下载下来,里面有一个cas-server-webapp的工程,使用Maven命令构建,导入到Eclipse中,便可以直接使用,cas server我使用的是3.5.2版本。客户端,我是使用以前的工程,只要是Web工程就行,cas-client使用的3.2.1,Spring Security使用的是3.1.4,记得Spring Security的3.1.2版本和CAS集成时,当需要CAS Server传比较多的信息给客户端时,客户端的Spring Security会解析出错(如果木有记错的话)
**PS:**无使用HTTPS协议,需要对CAS Server的配置做改动,具体后面详述
需要修改deployerConfigContext.xml,使用我们自己定义的类验证,配置文件如下:
package com.wds.security.cas;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.jasig.cas.authentication.handler.AuthenticationException;
import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.authentication.dao.SaltSource;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import com.wds.security.pojo.BaseUser;
import com.wds.security.pojo.BaseUserDetail;
public class UsernamePasswordJDBCAuthenticationHandler extends
AbstractUsernamePasswordAuthenticationHandler {
private JdbcTemplate jdbcTemplate;
private PasswordEncoder passEncoder;
private SaltSource saltSource;
@Override
protected boolean authenticateUsernamePasswordInternal(
UsernamePasswordCredentials credentials)
throws AuthenticationException {
final String username = credentials.getUsername();
final String password = credentials.getPassword();
String sql = " select * from base_user where status = 1 and user_account ='" + username + "'";
BaseUser baseUser = jdbcTemplate.queryForObject(sql, null, new RowMapper(){
@Override
public BaseUser mapRow(ResultSet rs, int rowNum)
throws SQLException {
BaseUser baseuser = new BaseUser();
baseuser.setCode(rs.getString("code"));
baseuser.setUserAccount(rs.getString("user_account"));
baseuser.setUserPassword(rs.getString("user_password"));
baseuser.setUserName(rs.getString("user_name"));
return baseuser;
}
});
List auth = new ArrayList();
GrantedAuthority ga = new SimpleGrantedAuthority("admin");
auth.add(ga);
BaseUserDetail user = new BaseUserDetail(username, baseUser.getUserName(), baseUser.getUserPassword(), baseUser.getCode(), true, true, true, true, auth);
if(user != null){
//验证密码
String encodePassword = this.passEncoder.encodePassword(password, this.saltSource.getSalt(user));
if(encodePassword.equals(user.getPassword())){
return true;
}
}
return false;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void setPassEncoder(PasswordEncoder passEncoder) {
this.passEncoder = passEncoder;
}
public void setSaltSource(SaltSource saltSource) {
this.saltSource = saltSource;
}
}
另外还有一个加密使用的类如下:
package com.wds.security.cas;
import org.jasig.cas.authentication.handler.PasswordEncoder;
import org.springframework.security.authentication.dao.SaltSource;
import org.springframework.security.authentication.encoding.MessageDigestPasswordEncoder;
import org.springframework.security.core.userdetails.UserDetails;
public class MD5PassworEncoder extends MessageDigestPasswordEncoder implements
PasswordEncoder {
private SaltSource saltSource;
private UserDetails user;
public MD5PassworEncoder(String algorithm) {
super("MD5");
}
@Override
public String encode(String password) {
return encodePassword(password, this.saltSource.getSalt(user));
}
public void setSaltSource(SaltSource saltSource) {
this.saltSource = saltSource;
}
public void setUser(UserDetails user) {
this.user = user;
}
}
当然,还有一些数据库的配置,文中不再列出了
package com.wds.security.cas;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jasig.cas.authentication.principal.Credentials;
import org.jasig.cas.authentication.principal.CredentialsToPrincipalResolver;
import org.jasig.cas.authentication.principal.Principal;
import org.jasig.cas.authentication.principal.SimplePrincipal;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
public class BaseUsernamePasswordCredentialsToPrincipalResolver implements
CredentialsToPrincipalResolver {
private static final Logger logger = LoggerFactory.getLogger(BaseUsernamePasswordCredentialsToPrincipalResolver.class);
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public Principal resolvePrincipal(Credentials credentials) {
UsernamePasswordCredentials up = (UsernamePasswordCredentials) credentials;
// 获取登录帐户
logger.debug("登录用户:" + up.getUsername());
// System.out.println(up.getPassword());
final Map attr = new HashMap();
String sql = "select resource_url from v_user_role_resources where user_account ='" + up.getUsername() + "'";
List list = jdbcTemplate.queryForList(sql, String.class);
attr.put(up.getUsername(), list);
Principal p = new SimplePrincipal(up.getUsername(), attr);
return p;
}
@Override
public boolean supports(Credentials credentials) {
return credentials != null
&& UsernamePasswordCredentials.class
.isAssignableFrom(credentials.getClass());
}
}
此外,还需要修改验证成功的JSP界面casServiceValidationSuccess.jsp,代码如下:
<%--
Licensed to Jasig under one or more contributor license
agreements. See the NOTICE file distributed with this work
for additional information regarding copyright ownership.
Jasig licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a
copy of the License at the following location:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
--%>
<%@ page session="false" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)}
${pgtIou}
${fn:escapeXml(proxy.principal.id)}
${fn:escapeXml(v)}
${fn:escapeXml(attr.value)}
至此,服务端配置完成,
SpringSecurity
配置文件中还有其它配置,是用来验证权限的,重点关注和CAS相类的配置即可