服务工作在可信空间中的网关之后(网关验证OAuth令牌,并只给服务唯一的用户ID,在其他情况下,它重定向认证服务)。
我想在服务中使用spring安全,以能够验证用户ID的权限。
因此,我添加了CustomUserDetailsService
@Service("userDetailsService") public class CustomUserDetailsService implements UserDetailsService { @Autowired(required = false) private ContextSsoActiveProfileIdProvider contextSsoActiveProfileIdProvider; @Autowired private GrantedAuthorityService grantedAuthorityService; @Override public User loadUserByUsername(final String username) throws UsernameNotFoundException { // verify it with authentication service, but there is not token, userId only, so trust to gateway service. return new User( String.valueOf(contextSsoActiveProfileIdProvider.getSsoActiveProfileId()), "authenticatedWithGateWay", grantedAuthorityService.getGrantedAuthoritiesForCurrentUser() ); } }
其中ContextsSOActiveProfileIdProvider.GetsSOActiveProfileId()返回uniqueUserId,GetGrantedAuthorityService.GetGrantedAuthoritiesForCurrentUser()返回权限。
服务在受信任区域中启动,因此我以以下方式配置了安全性:
@EnableWebSecurity @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/**").permitAll(); } @Override protected UserDetailsService userDetailsService() { return userDetailsService; } }
我需要为所有URI(HTTP.AuthorizeRequests().AntMatchers(“/**”).PermitAll();
)的所有用户提供自由访问(不触发登录服务),但似乎抑制了对下一个批注@preauthorize
、@prefilter
、@postauthorize
和@postfilter
的触发处理程序。
我想我在这里错误地使用了http.authorizeRequests().antmatchers(“/**”).PermitAll();
或其他配置部分。
更多问题症状:
CustomUserDetailsService.LoadUserByUserName(..)
从不调用;@AuthenticationPrincipal User ActiveUser
为空principal
上也为null可信空间问题有类似于匿名用户标识的解决方案(我在研究这个问题时已经得出了这个结论)
受信任的空间不需要授权,但不会调用UserDetailsService,因为默认情况下只使用AnonymousAuthenticationProvider
和AnonymousAuthenticationFilter
。基于AnonymousAuthenticationFilter
实现自定义筛选器已经足够好了,它覆盖CreateAuthentication
并用自定义筛选器(CustomAnonymousAuthenticationFilter
)替换默认值(AnonymousAuthenticationFilter
):
@Configuration public static class NoAuthConfigurationAdapter extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Autowired private IdentifiableAnonymousAuthenticationFilter identifiableAnonymousAuthenticationFilter; @Override protected void configure(HttpSecurity http) throws Exception { http.anonymous().authenticationFilter(identifiableAnonymousAuthenticationFilter); http.antMatcher("/**").authorizeRequests() .anyRequest().permitAll(); } }
我发现如果user没有得到授权,就永远不会调用CustomUserDetailsService。继续研究的重点是AnonymousAuthenticationFilter,它负责创建匿名用户信息。因此,其根本目的是用my IdentifiableAnonymousAuthenticationFilter替换AnonymousAuthenticationFilter,其中一些方法应该被覆盖:
@Component public class IdentifiableAnonymousAuthenticationFilter extends AnonymousAuthenticationFilter { public static final String KEY_IDENTIFIABLE_ANONYMOUS_AUTHENTICATION_FILTER = "Key.IdentifiableAnonymousAuthenticationFilter"; @Autowired private CustomUserDetailsService userDetailsService; @Autowired private GrantedAuthorityService grantedAuthorityService; private AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource(); public IdentifiableAnonymousAuthenticationFilter() { this(KEY_IDENTIFIABLE_ANONYMOUS_AUTHENTICATION_FILTER); } public IdentifiableAnonymousAuthenticationFilter(String key) { super(key); } @Override protected Authentication createAuthentication(HttpServletRequest request) { AnonymousAuthenticationToken auth = new AnonymousAuthenticationToken( KEY_IDENTIFIABLE_ANONYMOUS_AUTHENTICATION_FILTER, userDetailsService.loadCurrentUser(request), grantedAuthorityService.getGrantedAuthoritiesForCurrentUser()); auth.setDetails(authenticationDetailsSource.buildDetails(request)); return auth; } }
将其注入配置
@Configuration
public class IdentifyAnonymousConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private IdentifiableAnonymousAuthenticationFilter identifiableAnonymousAuthenticationFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.anonymous().authenticationFilter(identifiableAnonymousAuthenticationFilter);
// ... some other configurations
}
}
现在看来要好得多,因为identifiableAnonymousAuthenticationFilter被注入到AnonymousConfigurer中。请注意基于WebSecurityConfigurerAdapter
的配置。如果您只有几个,并且其中一个不会设置customAnonymousAuthenticationFilter,但配置得早于Custom..您将获得AnonymousAuthenticationFilter的默认实例(默认情况下在WebSecurityConfigurerAdapter
中配置):
protected final HttpSecurity getHttp() throws Exception { //... http .csrf().and() .addFilter(new WebAsyncManagerIntegrationFilter()) .exceptionHandling().and() .headers().and() .sessionManagement().and() .securityContext().and() .requestCache().and() .anonymous().and() // ...
如果应用程序被修复,我不会关心它,但是AnonymousAuthenticationFilter调用的时间早于IdentifiableAnonymousAuthenticationFilter。和doFilter将不正确
身份验证放入SecurityContextHolder。
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
if(SecurityContextHolder.getContext().getAuthentication() == null) {
SecurityContextHolder.getContext().setAuthentication(this.createAuthentication((HttpServletRequest)req));
if(this.logger.isDebugEnabled()) {
this.logger.debug("Populated SecurityContextHolder with anonymous token: '" + SecurityContextHolder.getContext().getAuthentication() + "'");
}
} else if(this.logger.isDebugEnabled()) {
this.logger.debug("SecurityContextHolder not populated with anonymous token, as it already contained: '" + SecurityContextHolder.getContext().getAuthentication() + "'");
}
chain.doFilter(req, res);
}
因此,当下次为IdentifiableAnonymousAuthenticationFilter调用doFilter时,由于条件if(SecurityContextHolder.getContext().getAuthentication()==null)
(请参阅前面的方法),它不会替换Authentication
。
因此,使用magic annotation@Order来管理配置加载顺序,为WebSecurityConfigurerAdapter
配置提供修复配置将是非常好的。
或者有人会想--在IdentifiableAnonymousAuthenticationFilter中无条件添加doFilter
重写(这是黑客):
@Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { SecurityContextHolder.getContext().setAuthentication(createAuthentication((HttpServletRequest) req)); if (logger.isDebugEnabled()) { logger.debug("Populated SecurityContextHolder with anonymous token: '" + SecurityContextHolder.getContext().getAuthentication() + "'"); } chain.doFilter(req, res); }
如果您需要处理授权/身份验证用户的spring安全,这是不可接受的,但在某些情况下,这就足够了。
解决办法的某些部分可以改进,但我希望这个想法总体上是清楚的。
我正在使用这个环境: Spring 4.0.5 Spring security 3.2.4 在我的环境中,我有一个SSO系统,我需要在这个系统中集成我的web应用程序。这个系统是私人产品。SSO机制的最终结果是在请求头中放置一个参数。所以我在申请中应该做的是: null 此场景类似于CAS集成场景;所以我从CAS集成着手;我写了我的自定义过滤器,我写了我的自定义入口点和处理请求所需的所有其他类,但
我们正在构建一个通过RabbitMQ接收消息的Spring Boot应用程序(2.0.4版本)。因此,包含与rabbit相关的配置: 配置: 原因:java.lang.IllegalArgumentException:类“My.Fancy.Package.Clazz”不在受信任的包[java.util,java.lang]中。如果您认为反序列化该类是安全的,请提供它的名称。如果序列化仅由受信任的源
我有一个带有OAuth2授权和资源服务器的Spring引导设置。用户可以通过向发出POST请求来获取令牌。到目前为止,一切都很好。 但是,我不想通过基本auth保护,而是通过自定义安全过滤器。 一些简单的例子如何实现这一点将是非常有帮助的。谢谢!
如何在链顶部的Spring Security链中插入多个自定义过滤器? 我可以通过在="FIRST"之后使用和之后尝试多个
我有一个Keycloak连接器,它允许我通过SSO检索用户的用户名。我想使用这个用户名来认证用户,并在数据库中查找他的权限,并将这个用户权限注入到spring security中,以便能够使用它的功能。 我用自定义的UserDetailsService创建了一个自定义的authenticationProvider,但我一直面临的问题是,我每次都被重定向到spring security登录页面。我认
问题内容: 如果我正在使用eval()评估Python字符串,并且具有类似这样的类: 如果我不信任该字符串,会有哪些安全风险?尤其是: 是eval(string, {“f”: Foo()}, {})不安全的?也就是说,你可以从Foo实例访问os或sys还是不安全的东西? 是eval(string, {}, {})不安全的?也就是说,我可以完全通过len和list之类的内置工具访问os或sys吗?