Java 除了基于令牌的身份验证之外,还允许Rest api端点使用http基本身份验证
我最近创建了一个jhipster应用程序,它包含以下.yo-rc.jsonJava 除了基于令牌的身份验证之外,还允许Rest api端点使用http基本身份验证,java,spring-security,spring-boot,jhipster,Java,Spring Security,Spring Boot,Jhipster,我最近创建了一个jhipster应用程序,它包含以下.yo-rc.json { "generator-jhipster": { "baseName": "cmpayments", "packageName": "au.com.cmx.myapp", "packageFolder": "au/com/cmx/myapp", "authenticationType": "token", "hibernateCache": "no", "clus
{
"generator-jhipster": {
"baseName": "cmpayments",
"packageName": "au.com.cmx.myapp",
"packageFolder": "au/com/cmx/myapp",
"authenticationType": "token",
"hibernateCache": "no",
"clusteredHttpSession": "no",
"websocket": "no",
"databaseType": "sql",
"devDatabaseType": "postgresql",
"prodDatabaseType": "postgresql",
"useCompass": false,
"buildTool": "maven",
"frontendBuilder": "gulp",
"javaVersion": "8"
}
}
我喜欢在webapp上使用基于令牌的身份验证,但我希望服务器只使用http基本身份验证公开restapi调用。我已经和Spring security搏斗了一段时间,但我对Spring security完全陌生,我希望有人已经这么做了,可以帮助我
我在这里尝试了以下解决方案:
我在SecurityConfiguration.java中用@Order(1)创建了第二个配置,如下所示
@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("api").password("pass").roles("API");
}
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/basicAuthApi/**").hasRole("API")
.and()
.httpBasic();
}
}
这很有效。如果我使用api/pass凭据以外的任何东西命中/basicAuthApi下的端点,我将得到一个401。耶
但是,在此之后,当我以admin/admin(或user/user)的身份登录到webapp时,我会以匿名用户的身份登录。如果我在SecurityConfiguration.java中注释掉额外的@Configuration并重新启动应用程序,这个问题就会消失,我将以管理员(或用户)的身份正确登录
有趣的是,我尝试将第二个@Configuration的顺序更改为@order(101),因为我在其中一个基类中看到了@order(100)。在这种情况下,webapp上的管理员和用户登录可以正常工作。但是RESTAPI调用不再安全,即即使密码不正确,它也会成功
有人知道我做错了什么吗
谢谢
dalyc我找到了一个适合我的解决方案。我意识到我不需要另一个@Configuration,因为默认的jhipster配置不会重定向到未经身份验证的访问的登录页面-它返回一个401,这也是我想要的RESTAPI。 因此,我刚刚注册了一个用户名和密码的用户,我想将其用于RESTAPI,并在中的configure方法底部添加了以下行 OAuth2ServerConfiguration.ResourceServerConfiguration
`.antMatchers("/basicAuthApi/**").hasAuthority(AuthoritiesConstants.USER).and().httpBasic();`
现在,我将尝试通过创建一个API角色并将该角色提供给需要调用RESTAPI的用户来改进这一点
如果有人知道的话,我仍然想知道为什么我最初的尝试会出现这些问题
干杯
dalyc关于顺序优先的介绍:如果不指定一个,则默认顺序是映射到最低可能优先级的最大可能数字(因为较低的顺序转换为较高的优先级)。因此,当您添加order=1的配置时,您有两个配置,order=1的新配置具有更高的优先级并首先被检查 在您描述的两种配置都存在的场景中,会发生以下情况:
您尝试以admin/admin(或user/user)的身份登录到webapp,但是spring安全性首先检查order=1的配置,该配置包含ant matcher
“.antMatchers(“/basicAuthApi/**”).hasRole(“API”)”
。它显然不匹配,因为您指向的url是网站的url,但是安全性不会失败,因为您缺少.anyRequest().authenticated()
,这是使未通过身份验证的用户的安全检查实际失败所需的。如果不这样做,您实际上通过了安全检查,尽管您没有经过身份验证,即您被视为具有匿名用户访问权限的匿名用户。由于该配置的spring security成功,它甚至不会检查与网站相关的另一个配置。替换原始的SecurityConfiguration。配置:
http
.csrf()
.ignoringAntMatchers("/websocket/**")
.and()
.addFilterAfter(new CsrfCookieGeneratorFilter(), CsrfFilter.class)
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.rememberMe()
.rememberMeServices(rememberMeServices)
.rememberMeParameter("remember-me")
.key(env.getProperty("jhipster.security.rememberme.key"))
.and()
.formLogin()
.loginProcessingUrl("/api/authentication")
.successHandler(ajaxAuthenticationSuccessHandler)
.failureHandler(ajaxAuthenticationFailureHandler)
.usernameParameter("j_username")
.passwordParameter("j_password")
.permitAll()
.and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler)
.deleteCookies("JSESSIONID")
.permitAll()
.and()
.headers()
.frameOptions()
.disable()
.and()
.authorizeRequests()
.antMatchers("/api/register").permitAll()
.antMatchers("/api/activate").permitAll()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/account/reset_password/init").permitAll()
.antMatchers("/api/account/reset_password/finish").permitAll()
.antMatchers("/api/logs/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/api/**").authenticated()
.antMatchers("/metrics/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/health/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/trace/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/dump/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/shutdown/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/beans/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/configprops/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/info/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/autoconfig/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/env/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/trace/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/api-docs/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/protected/**").authenticated();
通过这个:
http
.csrf()
.ignoringAntMatchers("/websocket/**")
.and()
.csrf()
.ignoringAntMatchers("/basicAuthApi/**")
.and()
.addFilterAfter(new CsrfCookieGeneratorFilter(), CsrfFilter.class)
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.rememberMe()
.rememberMeServices(rememberMeServices)
.rememberMeParameter("remember-me")
.key(env.getProperty("jhipster.security.rememberme.key"))
.and()
.formLogin()
.loginProcessingUrl("/api/authentication")
.successHandler(ajaxAuthenticationSuccessHandler)
.failureHandler(ajaxAuthenticationFailureHandler)
.usernameParameter("j_username")
.passwordParameter("j_password")
.permitAll()
.and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler)
.deleteCookies("JSESSIONID")
.permitAll()
.and()
.headers()
.frameOptions()
.disable()
.and()
.authorizeRequests()
.antMatchers("/api/register").permitAll()
.antMatchers("/api/activate").permitAll()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/account/reset_password/init").permitAll()
.antMatchers("/api/account/reset_password/finish").permitAll()
.antMatchers("/api/logs/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/api/**").authenticated()
.antMatchers("/metrics/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/health/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/trace/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/dump/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/shutdown/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/beans/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/configprops/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/info/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/autoconfig/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/env/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/trace/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/api-docs/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/protected/**").authenticated()
.and()
.authorizeRequests()
.antMatchers("/basicAuthApi/**")
.hasAuthority(AuthoritiesConstants.USER).and().httpBasic();
我只是补充说:
.and()
.csrf()
.ignoringAntMatchers("/basicAuthApi/**")
以及:
您还可以创建一个新的权限,该权限只能访问这些web服务
.and()
.authorizeRequests()
.antMatchers("/basicAuthApi/**")
.hasAuthority(AuthoritiesConstants.USER).and().httpBasic()