spring security 集成cas单点登录核心配置及相关java代码

最近项目中需要集成单点登录,所以最近研究了下,同时也在前面的章介绍了cas服务端的搭建,接下来security 集成cas 亲测可行,网上也是有很多不完整的代码,免得误导大家

1.web.xml配置



  kun-web
  
    contextConfigLocation
    
    
    
  	classpath:webApplication.xml,classpath:application.xml,classpath:applicationContext-security-cas.xml
  
  
  
    springSecurityFilterChain
    org.springframework.web.filter.DelegatingFilterProxy
  
  
    springSecurityFilterChain
    /*
  
  
    encodingFilter
    org.springframework.web.filter.CharacterEncodingFilter
    true
    
      encoding
      UTF-8
    
  
  
    encodingFilter
    /*
  
  
  
    kun_DispatcherServlet
    org.springframework.web.servlet.DispatcherServlet
    
      contextConfigLocation
      classpath:spring-mvc.xml
    
    1
    true
  
  
    kun_DispatcherServlet
    /
  
  
  
  
  
  
   
  		cn.com.wavenet.hydro.servlet.listener.GlobalRequestListener
   
 	
 	org.jasig.cas.client.session.SingleSignOutHttpSessionListener
   
   
  
    log4jConfigLocation
    classpath:log4j.properties
  
  
  
    30
  
  
    /home
  
2.核心applicationContext-security-cas.xml配置




	
	
	
	
	
	
	
	
	

	
		
			
		
		
		
		
		
		
		
	

	
		
	
	
	
		
		
		
	

	
	
	
	
      
    	  
    

	
		
		
			
				
			
		
		
			
			
				
			
		
	

	
		
		
	

	
		
		
		
			
				
			
		
		
	

	
		
		
	

3.cas.properties文件

#cas 服务端地址
#cas.server.url=https://localhost:8090/cas

#cas 服务端登录地址
#cas.server.loginUrl=https://localhost:8090/cas/login

#对公司负责所以加了点,没删除是因为是http协议,http和https决定权在cas服务端,客户端是都可以使用的
cas.server.url=http://172.84.99.=2:8767/cas
cas.server.loginUrl=http://1724.4.4=1.=4:8767/cas/login

#是否开启强制登录验证,默认false
cas.server.renew=false  

#客户端地址
casClientRoot=http://localhost:8080/kun-web

4.核心java类UserDetailsService,在很多地方都是实现org.springframework.security.core.userdetails.UserDetailsService这其实是不对的,在非单点登录的情况下实现它是没错的但是在集成cas后,应该去实现org.springframework.security.core.userdetails.AuthenticationUserDetailsService,代码如下

package cn.com.wavenet.security.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.security.cas.authentication.CasAssertionAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Repository;

import cn.com.wavenet.hydro.dao.ResourceDao;
import cn.com.wavenet.hydro.dao.UsersDao;
import cn.com.wavenet.hydro.pojo.Resources;
import cn.com.wavenet.hydro.pojo.Users;
import cn.com.wavenet.security.filter.WavenetUser;

@Repository("cn.com.wavenet.security.service.UserDetailsService")
public class UserDetailsService implements AuthenticationUserDetailsService {
	
	private static final Logger logger = Logger.getLogger(UserDetailsService.class);  
	
	@Resource
	ResourceDao  resourceDao;
	
	@Resource
	UsersDao  wsurepos;
	
	@Resource
	WavenetResourceService wavenetResourceServiceImpl;
	
	@Override
	public UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException {
		List auths = new ArrayList();
		CasAssertionAuthenticationToken casauth = null;
		if (token instanceof CasAssertionAuthenticationToken) {
			casauth = (CasAssertionAuthenticationToken) token;
			Map attr = casauth.getAssertion().getPrincipal()
					.getAttributes();
			String username = attr.get("st_lgnm").toString();
			if(username == null || username=="" || username.equals("")) {
				String message = "用户:["+username +"]不存在";
				logger.error(message);
				throw new UsernameNotFoundException(message);
			}
			
			Users users = wsurepos.findByStLgnm(username);
			
			//h获取用户信息
			Collection grantedAuths = obtionGrantedAuthorities(users);
			List resourceList = resourceDao.getUserResourceByLgnm(username);
			boolean enables = true;
			boolean accountNonExpired = true;
			boolean credentialsNonExpired = true;
			boolean accountNonLocked = true;
			WavenetUser userdetail = new WavenetUser(users.getStLgnm(), users.getStLgps(), enables, accountNonExpired, credentialsNonExpired, accountNonLocked, grantedAuths);
			//org.springframework.security.core.userdetails.User user = new 
			//UserDetails userdetail = new 
			userdetail.setUsercode(users.getCdUs());
			userdetail.setResourceList(resourceList);
			Users nuser = new Users();
			nuser.setCdUs(users.getCdUs());
			nuser.setStAreaid(users.getStAreaid());
			nuser.setStName(users.getStName());
			userdetail.setUsers(nuser);
			return userdetail;
			
		}
		return null;
	}
	//取得用户的权限
	private Set obtionGrantedAuthorities(Users user) {
		Set authSet = new HashSet();
		List resources =wavenetResourceServiceImpl.getUserResourceByLgnm(user.getStLgnm());
		for(Resources resource : resources) {
			if (logger.isDebugEnabled()) {
				logger.debug("用户:[" + user.getStLgnm() + "]拥有资源:["
						+ resource.getStAph() + "],即spring security中的access");
			}
			try {
				if(null==resource || null==resource.getStAph()){
					continue;
				}
				authSet.add(new SimpleGrantedAuthority(resource.getStAph()));
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("="+e.getMessage());
			}
		
		}
		if (logger.isDebugEnabled()) {
			logger.debug("loadUserByUsername(String) - end"); 
		}
		return authSet;
	}

}
5.非cas的配置文件大家可以对比一下



	 
	
	 
	
	
	
	
	
	
	
	
	
		
		
		
        
        
	    
			 	
		
	

	
    
         
        
          
        
          
        
    
    
	
     
        
        	
        		
        	
          
    
      
      
    
      
    	  
    
    
    
    
    	
	
    


整个核心的代码就算完成了,后期我会抽时间补上源代码
过程中楼主遇到过如下几个问题,需要了解的可以留言

1.cas服务端登录成功后页面提示客户端未授权

2.cas服务端登录成功后客户端获取不到用户名

3.客户端获取到用户名后提示如下错误

HTTP Status 500 - javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present

4.本地测试成功,放到服务器后报相关错误

你可能感兴趣的:(java,spring,cas,单点登录)