2012-11-05 76 views
2

我是Spring Security和CAS的新手。我得到了SSO部分的工作,但我正在努力争取授权部分的工作。我跟着这个实现自定义授权春季安全与CAS认证和定制授权

http://www.theserverside.com/tip/-Spring-Security-Customizing-Your-User-and-Authorization-in

应该在什么时候loadUserDetails被调用。我在这里设置了一个断点,并且此方法从未被调用。

任何帮助将不胜感激。看起来我缺少一个配置来调用授权。

我想让我的自定义用户对象填充权限并驻留在会话中,以便我可以在任何阶段检查用户角色。

当我在这里登录日志是发生一次我登录

1. /indexCasePackOptions?ticket=ST-4295-4eFUHVziBcmVaOd3bifl-cas at position 1 of 8 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' (FilterChainProxy:329) 

No HttpSession currently exists (HttpSessionSecurityContextRepository:127) 

No SecurityContext was available from the HttpSession: null. A new one will be created. (HttpSessionSecurityContextRepository:85) 

2. /indexCasePackOptions?ticket=ST-4295-4eFUHVziBcmVaOd3bifl-cas at position 2 of 8 in additional filter chain; firing Filter: 'CasAuthenticationFilter' (FilterChainProxy:329) 

3. /indexCasePackOptions?ticket=ST-4295-4eFUHVziBcmVaOd3bifl-cas at position 3 of 8 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' (FilterChainProxy:329) 

4. /indexCasePackOptions?ticket=ST-4295-4eFUHVziBcmVaOd3bifl-cas at position 4 of 8 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' (FilterChainProxy:329) 

5. /indexCasePackOptions?ticket=ST-4295-4eFUHVziBcmVaOd3bifl-cas at position 5 of 8 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' (FilterChainProxy:329) 

Populated SecurityContextHolder with anonymous token: 'org.sprin[email protected]6faa93c2: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]ffffe21a: RemoteIpAddress: 192.168.0.124; SessionId: null; Granted Authorities: ROLE_ANONYMOUS' (AnonymousAuthenticationFilter:102) 

6. /indexCasePackOptions?ticket=ST-4295-4eFUHVziBcmVaOd3bifl-cas at position 6 of 8 in additional filter chain; firing Filter: 'SessionManagementFilter' (FilterChainProxy:329) 

7. /indexCasePackOptions?ticket=ST-4295-4eFUHVziBcmVaOd3bifl-cas at position 7 of 8 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' (FilterChainProxy:329) 

8. /indexCasePackOptions?ticket=ST-4295-4eFUHVziBcmVaOd3bifl-cas at position 8 of 8 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' (FilterChainProxy:329) 

Checking match of request : '/indexcasepackoptions'; against '/login/**' (AntPathRequestMatcher:103) 

Secure object: FilterInvocation: URL: /indexCasePackOptions?ticket=ST-4295-4eFUHVziBcmVaOd3bifl-cas; Attributes: [ROLE_ANONYMOUS] (FilterSecurityInterceptor:193) 

Previously Authenticated: org.sprin[email protected]6faa93c2: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]ffffe21a: RemoteIpAddress: 
192.168.0.124; SessionId: null; Granted Authorities: ROLE_ANONYMOUS (FilterSecurityInterceptor:298) 

Voter: [email protected], returned: 1 (AffirmativeBased:65) 

Authorization successful (FilterSecurityInterceptor:214) 

RunAsManager did not change Authentication object (FilterSecurityInterceptor:226) 

/indexCasePackOptions?ticket=ST-4295-4eFUHVziBcmVaOd3bifl-cas reached end of additional filter chain; proceeding with original chain (FilterChainProxy:315) 

No Proxy Ticket found for (ProxyGrantingTicketStorageImpl:77) 

SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession. (HttpSessionSecurityContextRepository:269) 

Chain processed normally (ExceptionTranslationFilter:115) 

SecurityContextHolder now cleared, as request processing completed (SecurityContextPersistenceFilter:97)  

我定制的UserDetails步骤

package com.creata.domain; 

import java.io.Serializable; 
import java.util.ArrayList; 
import java.util.Collection; 
import java.util.List; 

import org.springframework.security.core.GrantedAuthority; 
import org.springframework.security.core.authority.GrantedAuthorityImpl; 
import org.springframework.security.core.authority.SimpleGrantedAuthority; 
import org.springframework.security.core.userdetails.UserDetails; 

public class User implements Serializable, UserDetails { 

private static final long serialVersionUID = 1L; 
private Collection<SimpleGrantedAuthority> authorities; 
private final String username; 
private String password; 

public User(String username) { 
    this.username=username; 
} 

@Override 
public Collection<SimpleGrantedAuthority> getAuthorities() { 
    return authorities; 

} 
public void setUserAuthorities(List<String> roles) { 
    List<SimpleGrantedAuthority> listOfAuthorities = new ArrayList<SimpleGrantedAuthority>(); 
    for (String role : roles) { 
     listOfAuthorities.add(new SimpleGrantedAuthority(role)); 
    } 
    authorities = listOfAuthorities; 
} 

@Override 
public String getPassword() { 
    return this.password; 
} 

@Override 
public String getUsername() { 
    return username; 
} 

@Override 
public boolean isAccountNonExpired() { 
    return false; 
} 

@Override 
public boolean isAccountNonLocked() { 
    return false; 
} 

@Override 
public boolean isCredentialsNonExpired() { 
    return false; 
} 

@Override 
public boolean isEnabled() { 
    return true; 
} 

}

我定制UserService

package com.creata.security.service; 

import java.util.ArrayList; 
import java.util.List; 

import org.springframework.security.core.Authentication; 
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; 
import org.springframework.security.core.userdetails.UserDetails; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.core.userdetails.UsernameNotFoundException; 
import com.creata.domain.User; 

public class CustomUserService implements UserDetailsService, AuthenticationUserDetailsService { 

@Override 
public UserDetails loadUserByUsername(String username) 
     throws UsernameNotFoundException { 
    System.out.println("loadUserByUsername called here "); 
    User currentUser = new User("Reena"); 
    //Collection<SimpleGrantedAuthority> authorities = currentUser.getAuthorities(); 
    List<String> roles = new ArrayList<String>(); 
    roles.add("ROLE_Admin"); 
    roles.add("ROLE_CPAD-Maintenance"); 
    currentUser.setUserAuthorities(roles); 
    //authorities.add(new SimpleGrantedAuthority("PRIVILEGE_HOME")); 
    return currentUser; 
} 

@Override 
public UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException{ 
    User currentUser = new User("Reena"); 
    List<String> roles = new ArrayList<String>(); 
    roles.add("ROLE_Admin"); 
    roles.add("ROLE_CPAD-Maintenance"); 
    currentUser.setUserAuthorities(roles); 
    //authorities.add(new SimpleGrantedAuthority("PRIVILEGE_HOME")); 
    return currentUser; 
} 
} 

她的e是我的安全配置:

<beans:beans 
xmlns="http://www.springframework.org/schema/security" 
xmlns:beans="http://www.springframework.org/schema/beans" 
xmlns:p="http://www.springframework.org/schema/p" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:lang="http://www.springframework.org/schema/lang" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:aop="http://www.springframework.org/schema/aop" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
    http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security-3.1.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.1.xsd"> 

<http entry-point-ref="casEntryPoint"> 
    <custom-filter position="CAS_FILTER" ref="casFilter" /> 
</http> 

<authentication-manager alias="authenticationManager"> 
    <authentication-provider ref="casAuthenticationProvider" /> 
</authentication-manager> 

<beans:bean id="casFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter"> 
    <beans:property name="authenticationManager" ref="authenticationManager"/> 
</beans:bean> 

<beans:bean id="casEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint"> 
    <beans:property name="loginUrl" value="https://abc.com/cas/login"/> 
    <beans:property name="serviceProperties" ref="serviceProperties"/> 
</beans:bean> 

<beans:bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider"> 
    <beans:property name="authenticationUserDetailsService" ref="customUserService"/> 
    <beans:property name="serviceProperties" ref="serviceProperties" /> 
    <beans:property name="ticketValidator"> 
    <beans:bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator"> 
     <beans:constructor-arg index="0" value="https://portal.creata.com/cas" /> 
    </beans:bean> 
    </beans:property> 
    <beans:property name="key" value="an_id_for_this_auth_provider_only"/> 
</beans:bean> 

<beans:bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties"> 
    <beans:property name="service" value="https://mypc.abc.com/Spring_CPAD2/"/> 
</beans:bean> 

<beans:bean id="customUserService" class="com.creata.security.service.CustomUserService"/> 
</beans:beans>  

这里是我的web.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<web-app xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
metadata-complete="true"> 
<display-name /> 

<context-param> 
    <param-name>serverName</param-name> 
    <param-value>https://cpaus-rsingh2.creata.com</param-value> 
</context-param> 
<filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter>  
<filter> 
    <filter-name>characterEncodingFilter</filter-name> 
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 
    <init-param> 
     <param-name>encoding</param-name> 
     <param-value>UTF-8</param-value> 
    </init-param> 
</filter>  
<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping>  
<filter-mapping> 
    <filter-name>characterEncodingFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
<listener> 
    <listener-class> 
     org.springframework.web.context.request.RequestContextListener 
    </listener-class> 
</listener> 
<listener> 
    <listener-class> 
     org.springframework.web.context.ContextLoaderListener 
    </listener-class> 
</listener> 
<filter> 
    <filter-name>CAS Single Sign Out Filter</filter-name> 
    <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class> 
</filter> 
<filter> 
    <filter-name>CAS Authentication Filter</filter-name> 
    <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class> 
    <init-param> 
     <param-name>casServerLoginUrl</param-name> 
     <param-value>https://abc.com/cas/login?AppName=app1</param-value> 
    </init-param> 
</filter> 
<filter> 
    <filter-name>CAS Validation Filter</filter-name> 
    <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class> 
    <init-param> 
     <param-name>casServerUrlPrefix</param-name> 
     <param-value>https://abc.com/cas</param-value> 
    </init-param> 
</filter> 
<filter> 
    <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> 
    <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>CAS Single Sign Out Filter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
<filter-mapping> 
    <filter-name>CAS Authentication Filter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
<filter-mapping> 
    <filter-name>CAS Validation Filter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
<filter-mapping> 
    <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
<listener> 
    <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class> 
</listener> 
<filter> 
    <filter-name>ResponseOverrideFilter</filter-name> 
    <filter-class>org.displaytag.filter.ResponseOverrideFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>ResponseOverrideFilter</filter-name> 
    <url-pattern>*.jsp</url-pattern> 
    </filter-mapping> 
<filter> 
    <description>generated-persistence-filter</description> 
    <filter-name>com_ibm_db2_jcc_DB2DriverFilter</filter-name> 
    <filter-class> 
     org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter 
    </filter-class> 
    <init-param> 
     <param-name>entityManagerFactoryBeanName</param-name> 
     <param-value>com_ibm_db2_jcc_DB2Driver</param-value> 
    </init-param> 
</filter> 
<filter> 
    <description>generated-sitemesh-filter</description> 
    <filter-name>Sitemesh Filter</filter-name> 
    <filter-class> 
     com.opensymphony.module.sitemesh.filter.PageFilter 
    </filter-class> 
</filter> 
<!-- <filter> 
    <description>generated-persistence-filter</description> 
    <filter-name>MyEclipse_DerbyFilter</filter-name> 
    <filter-class> 
     org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter 
    </filter-class> 
    <init-param> 
     <param-name>entityManagerFactoryBeanName</param-name> 
     <param-value>MyEclipse_Derby</param-value> 
    </init-param> 
</filter> --> 
<filter-mapping> 
    <filter-name>com_ibm_db2_jcc_DB2DriverFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
<filter-mapping> 
    <filter-name>Sitemesh Filter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
<!-- <filter-mapping> 
    <filter-name>MyEclipse_DerbyFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> --> 
<servlet> 
    <description>generated-servlet</description> 
    <servlet-name>Spring_CPAD2 Servlet</servlet-name> 
    <servlet-class> 
     org.springframework.web.servlet.DispatcherServlet 
    </servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value> 
      classpath:Spring_CPAD2-web-context.xml 
     </param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 
<servlet> 
    <description>generated-resources-servlet</description> 
    <servlet-name>Resource Servlet</servlet-name> 
    <servlet-class> 
     org.springframework.js.resource.ResourceServlet 
    </servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet> 
<servlet> 
    <description>generated-webflow-servlet</description> 
    <servlet-name>webflow</servlet-name> 
    <servlet-class> 
     org.springframework.web.servlet.DispatcherServlet 
    </servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value> 
      /WEB-INF/config/Spring_CPAD2-webflow-config.xml 
     </param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 
<servlet-mapping> 
    <servlet-name>Resource Servlet</servlet-name> 
    <url-pattern>/resources/*</url-pattern> 
</servlet-mapping> 
<servlet-mapping> 
    <servlet-name>Spring_CPAD2 Servlet</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping> 
<servlet-mapping> 
    <servlet-name>webflow</servlet-name> 
    <url-pattern>*.flow</url-pattern> 
</servlet-mapping> 
<welcome-file-list> 
    <welcome-file>jsp/intro.jsp</welcome-file> 
</welcome-file-list> 
    <jsp-config> 
     <taglib> 
      <taglib-uri>MyCustomTags</taglib-uri> 
      <taglib-location>/WEB-INF/tlds/MyCustomTags.tld</taglib-location> 
     </taglib> 
    </jsp-config> 

+0

我应该调试代码的客户端来查看为什么我的自定义UserDetails没有被调用,或者发生在CAS服务器端吗?对不起,如果这听起来像一个基本的问题,我无法解决这个问题,并感到困惑。在我的Controller SecurityContextHolder.getContext()。getAuthentication()。getPrincipal();让我AnonymousUser。我如何获得我已经实现的UserDetails?有人请给我看光 – rdev

+0

@rodrigoap我看到你的答案在http://stackoverflow.com/questions/1322135/spring-security-authorization-without-authentication你能帮我解决问题吗?我是否需要创建一个预认证过滤器?我的方法不正确。我错过了什么? – rdev

+0

你解决了这个问题吗?我有同样的确切问题,我不能解决它,如果你解决了问题,你可以请发布答案 – engma

回答

2

CasAuthenticationProvider电话的UserDetailsS​​ervice仅在认证为null

我会建议把一个调试点在CasAuthenticationProvider.java中(请参考我在下面的代码中的注释)

public class CasAuthenticationProvider { 
public Authentication authenticate(Authentication authentication) throws AuthenticationException { 

    CasAuthenticationToken result = null; 

    if (stateless) { 
     // Try to obtain from cache 
     result = statelessTicketCache.getByTicketId(authentication.getCredentials().toString()); 
    } 

    if (result == null) { 
     //following line calls userDetailsService. I would recommend to put a debug point here 
     ///if it is not calling userDetailsService, that means result is not null 

     result = this.authenticateNow(authentication); 
     result.setDetails(authentication.getDetails()); 
    } 

    if (stateless) { 
     // Add to cache 
     statelessTicketCache.putTicketInCache(result); 
    } 

    return result; 
} 

您可以从http://mvnrepository.com/artifact/org.springframework.security/spring-security-cas-client下载源代码并将其附加到eclipse中。

+0

感谢您查看我的问题,我按照您的建议放入了中断点,但是当我登录时,此方法不会被调用。我可以尝试的其他任何事情? @Saurabh – rdev

+0

我阅读http://static.springsource.org/spring-security/site/docs/3.1.x/reference/cas。为了使CAS运行,ExceptionTranslationFilter必须将其authenticationEntryPoint属性设置为CasAuthenticationEntryPoint bean。我添加<豆:豆ID = “的ExceptionTranslationFilter” 类= “org.springframework.security.web.access.ExceptionTranslationFilter”> \t \t <豆:构造精氨酸REF = “casEntryPoint”/> \t \t但仍CasAuthenticationProvider没有被调用 – rdev

+0

@rsingh - 我注意到用户已经登录-n – Saurabh