如何在 SAML 中创建内存用户 [英] How to create an in memory user in SAML

查看:54
本文介绍了如何在 SAML 中创建内存用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在以下链接的帮助下使用 spring boot 1.4.0+spring-security-saml2-core 1.0.2 Spring-Boot-Saml-example 它运行良好.现在我想创建一个与 SAML 用户具有相同授予权限的内存用户.请找到以下 SAMLUserDetailsS​​erviceImpl 代码以供参考.您的帮助应该是可观的.

Hi I am using spring boot 1.4.0+spring-security-saml2-core 1.0.2 with the help of following link Spring-Boot-Saml-example it is working great. Now i would like to create an in memory user with the same granted authorities that the SAML user is issued.Kindly find the below code of SAMLUserDetailsServiceImpl for reference.Your help should be appreciable.

@Service
public class SAMLUserDetailsServiceImpl implements SAMLUserDetailsService {

// Logger
private static final Logger LOG = LoggerFactory.getLogger(SAMLUserDetailsServiceImpl.class);

@Value("${emailSamlAttrName}")
private String emailSamlAttrName;

public Object loadUserBySAML(SAMLCredential credential)
        throws UsernameNotFoundException {

    // The method is supposed to identify local account of user referenced by
    // data in the SAML assertion and return UserDetails object describing the user.

    String userID = credential.getNameID().getValue();
    Attribute emailAttribute = credential.getAttribute(emailSamlAttrName);
    String userEmail = getAttributeValue(credential.getAttribute(emailSamlAttrName).getAttributeValues().get(0));
    LOG.info(userID + " is logged in");
    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
    authorities.add(authority);

    // In a real scenario, this implementation has to locate user in a arbitrary
    // dataStore based on information present in the SAMLCredential and
    // returns such a date in a form of application specific UserDetails object.
    return new User(userID, "<abc123>", true, true, true, true, authorities);
}

根据@blur0224 评论,我将以下代码放入:

As per the @blur0224 comment i put the following code in:

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
      auth.inMemoryAuthentication().withUser("sample").password("sample123").roles("NONE");
      auth.inMemoryAuthentication().withUser("dummy").password("dummy123").roles("USER");
      auth.inMemoryAuthentication().withUser("proxy").password("proxy123").roles("USER");
}

但它抛出以下错误....

But it throws the following error....

11:09:41.345 [http-nio-8040-exec-1] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor [transactionId: ]- Secure object:   FilterInvocation: URL: /api/v1/users/authenticated; Attributes:    [hasRole('ROLE_NONE') or hasRole('ROLE_USER')]
11:09:41.345 [http-nio-8040-exec-1] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor [transactionId: ]- Previously Authenticated:   org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2b    c: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true;   Details:   org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
11:09:41.351 [http-nio-8040-exec-1] DEBUG o.s.s.access.vote.AffirmativeBased [transactionId: ]- Voter: org.springframework.security.web.access.expression.WebExpressionVoter@2809e0b9, returned: -1
11:09:41.352 [http-nio-8040-exec-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory [transactionId: ]- Returning cached instance of singleton bean 'delegatingApplicationListener'
11:09:41.352 [http-nio-8040-exec-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory [transactionId: ]- Returning cached instance of singleton bean 'authorizationAuditListener'
11:09:41.354 [http-nio-8040-exec-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory [transactionId: ]- Returning cached instance of singleton bean 'delegatingApplicationListener'
11:09:41.354 [http-nio-8040-exec-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory [transactionId: ]- Returning cached instance of singleton bean 'auditListener'
11:09:41.354 [http-nio-8040-exec-1] DEBUG o.s.b.a.audit.listener.AuditListener [transactionId: ]- AuditEvent [timestamp=Wed Jul 27 11:09:41 CEST 2016, principal=anonymousUser, type=AUTHORIZATION_FAILURE, data={type=org.springframework.security.access.AccessDeniedException, message=Access is denied}]
11:09:41.359 [http-nio-8040-exec-1] DEBUG o.s.s.w.a.ExceptionTranslationFilter [transactionId: ]- Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
at  org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:232)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:123)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:207)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:184)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.saml.metadata.MetadataGeneratorFilter.doFilter(MetadataGeneratorFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:103)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:676)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

WebSecurityConfig.java

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .httpBasic()
            .authenticationEntryPoint(samlEntryPoint());
    http
        .csrf()
            .disable();
    http
        .addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class)
        .addFilterAfter(samlFilter(), BasicAuthenticationFilter.class);
    http
        .authorizeRequests()
        .antMatchers("/error").permitAll()
        .antMatchers("/saml/**").permitAll()
        .antMatchers("/api/*/users/authenticated").access(String.format("hasRole('%s') or hasRole('%s')", ROLE_NONE, ROLE_USER))
        .antMatchers("/api/**").access(String.format("hasRole('%s')", ROLE_USER))
        .anyRequest().access(String.format("hasRole('%s')", ROLE_USER));
    http
        .logout()
            .logoutSuccessUrl("/");
}

推荐答案

在您的 SAMLUserDetailsS​​erviceImpl 中,您当前没有在数据库中查找用户以获取有关他们的任何特定信息.在这种情况下,您可以设置本地安全配置,以在内存中创建用户,其授予的权限与他们通过 SAML 时拥有的权限相同.ROLE_USER 您可以使用下面的示例作为指南来设置您可以像本地开发一样登录的用户.

In your SAMLUserDetailsServiceImpl you are currently not looking up the user in a DB to get any specific information about them. This being the case, you can setup your local security configuration to create in memory users with the same granted authority they have when they go through SAML. ROLE_USER You can use the example below as a guide for setting up a user that you can log in as for your local development.

内存用户示例

你错过了吗?

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/info/**").hasAnyRole("ADMIN","USER").
        and().formLogin();
    }

您需要两个单独的安全配置:WebSecurityConfigLocalSecurityConfig 在本地运行时,您需要最快速、最简单的方法来复制您的 saml 实现为您提供的内容,即具有授予权限的用户.请注意,您的 SAML 配置文件需要 @Profile("dev","test","prod") WebSecurityConfig

You need two separate security configurations: WebSecurityConfig and LocalSecurityConfig When running locally you want the quickest, easiest way to replicate what your implementation of saml provides you with, which is a user with granted authorities. Note that you will need to have @Profile("dev","test","prod") on your SAML Configuration files WebSecurityConfig

@Configuration
@ComponentScan("com.whatever.etc")
@EnableWebSecurity
@Profile("local")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/**").hasAnyRole("ADMIN","USER").
        and().httpBasic();
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
          auth.inMemoryAuthentication().withUser("ram").password("ram123").roles("ADMIN");
          auth.inMemoryAuthentication().withUser("ravan").password("ravan123").roles("USER");
          auth.inMemoryAuthentication().withUser("kans").password("kans123").roles("USER");
    }
}   

您不能简单地将用户添加到 SAML 配置中,因为它具有不同的入口点.通过创建单独的配置,您可以精细控制您希望应用程序如何仅在本地运行.此外,可以但没有必要将两个配置合并到一个文件中.我建议先让他们分开工作.

You can't simply add users to the SAML configuration because the it has a different entry point. By creating a separate configuration, you have granular control of how you want the application to behave running locally only. Also, it is possible but not necessary to combine the two configurations into a single file. I would recommend getting them working separately first.

这篇关于如何在 SAML 中创建内存用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆