我最近创建了一个带有以下.yo-rc.json
的jhipster应用程序{
"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基本身份验证来公开REST api调用。我已经和我争吵了一段时间,但我对Spring安全完全不熟悉,我希望有人已经这样做了,可以帮助我。
我尝试按照此处的解决方案: Basic and form based authentication with Spring security Javaconfig
我在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();
}
}
这很有效。如果我在/ basicAuthApi下使用api / pass凭证以外的其他任何一个端点,我得到401. Yay。
然而,在此之后,当我以admin / admin(或用户/用户)身份登录webapp时,我以anonymousUser身份登录。如果我在SecurityConfiguration.java中注释掉额外的@Configuration并重新启动应用程序,那么问题就会消失,我会以管理员(或用户)的身份正确登录。
有趣的是,我尝试将第二个@Configuration的顺序更改为@Order(101),因为我在其中一个基类中看到了某个@Order(100)。在这种情况下,webapp上的管理员和用户登录工作。但其余的api调用不再安全,即使密码错误也能成功。
有谁知道我做错了什么?
由于 dalyc
答案 0 :(得分:2)
替换原来的SecurityConfiguration.configure:
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/**")
和:
.and()
.authorizeRequests()
.antMatchers("/basicAuthApi/**")
.hasAuthority(AuthoritiesConstants.USER).and().httpBasic()
您还可以创建一个只能访问这些Web服务的新权限。
答案 1 :(得分:0)
我找到了一个适合我的解决方案。我意识到我不需要另一个@Configuration,因为默认的jhipster配置没有重定向到登录页面以进行未经身份验证的访问 - 它返回一个401,这也是我想要的REST api。 所以我只是注册了一个用户,其中包含我想用于REST API的用户名和密码,并将以下行添加到
中的configure方法的底部OAuth2ServerConfiguration.ResourceServerConfiguration
`.antMatchers("/basicAuthApi/**").hasAuthority(AuthoritiesConstants.USER).and().httpBasic();`
我现在将尝试通过创建API角色并将该角色提供给需要调用REST API的用户来改进这一点
如果有人知道,我仍然想知道为什么我最初的尝试会遇到这些问题。
干杯 dalyc
答案 2 :(得分:0)
关于订单的介绍:如果您没有指定一个默认订单,则是可能的最大数字,它映射到可能的最低优先级(因为较低的顺序转换为较高的优先级)。因此,当您添加order = 1的配置时,您有两个配置,其中order = 1的新配置具有更高的优先级并首先进行检查。
在描述两种配置存在的场景中,会发生以下情况:
您尝试以admin / admin(或用户/用户)身份登录webapp,但spring security首先检查order = 1的配置,该配置包含ant匹配器" .antMatchers("/basicAuthApi/**").hasRole("API")"
。它显然不匹配,因为您指向的网址是网站的网址,但是安全性不会因为您缺少.anyRequest().authenticated()
而失败,以便对于未能成功的用户进行安全检查认证。如果没有这个,您实际上会通过安全检查,尽管您未经过身份验证,即您被视为具有匿名用户访问权限的匿名用户。由于该配置的Spring安全性成功,因此它甚至不会检查与该网站相关的另一个。