[英]Spring security OAuth2 authentication and form login in one app
Is it possible to combine authoryzation and authentication by login basic and by oauth2 in one application? 是否可以通过login basic和oauth2在一个应用程序中组合authoryzation和身份验证?
My project is based on jhipster project with simple spring security session login, now i need add oauth2 security for mobile app and it's look like it is not possible. 我的项目基于jhipster项目,简单的弹簧安全会话登录,现在我需要为移动应用程序添加oauth2安全性,看起来它是不可能的。
Now i have situation when work one of them, oauth2 ok if WebSecurityConfigurerAdapter had bigger order number than ResourceServerConfiguration. 现在我有工作其中一个的情况,oauth2确定如果WebSecurityConfigurerAdapter的订单号比ResourceServerConfiguration更大。 That's mean if oauth security filter is first.
这意味着如果首先是oauth安全过滤器。 I read a lot in stackoverflow and try many solution like: Spring security oauth2 and form login configuration for me thats one don't work.
我在stackoverflow中阅读了很多内容并尝试了许多解决方案,例如: Spring security oauth2和表单登录配置,对我来说这是不行的。
Now i know that is related with some security filter conflict but i dont know how to fix it. 现在我知道这与一些安全过滤器冲突有关,但我不知道如何解决它。
if someone had a similar problem and he managed to do it, or know how to get around or make it better I will be grateful for the information. 如果有人有类似的问题并且他设法做到了,或者知道如何绕过或做得更好,我会很感激这些信息。 Thanks in advance for your help :)
在此先感谢您的帮助 :)
@Configuration
@EnableWebSecurity
public class SecurityOauth2Configuration extends WebSecurityConfigurerAdapter {
@Inject
private UserDetailsService userDetailsService;
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/scripts/**/*.{js,html}")
.antMatchers("/bower_components/**")
.antMatchers("/i18n/**")
.antMatchers("/assets/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/api/register")
.antMatchers("/api/activate")
.antMatchers("/api/account/reset_password/init")
.antMatchers("/api/account/reset_password/finish")
.antMatchers("/test/**");
}
@Configuration
@EnableAuthorizationServer
public static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private static final String OAUTH_SECURITY = "jhipster.security.authentication.oauth.";
private static final String CLIENTID = "clientid";
private static final String SECRET = "secret";
private static final String TOKEN_VALIDATION_TIME = "tokenValidityInSeconds";
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("isAnonymous() || hasAuthority('"+AuthoritiesConstants.USER+"')").checkTokenAccess("hasAuthority('"+AuthoritiesConstants.USER+"')");
}
@Inject
private Environment env;
@Inject
private DataSource dataSource;
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.tokenStore(tokenStore())
;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient(env.getProperty(OAUTH_SECURITY + CLIENTID))
.scopes("read", "write")
.authorities(AuthoritiesConstants.ADMIN, AuthoritiesConstants.USER)
.authorizedGrantTypes("password", "refresh_token")
.secret(env.getProperty(OAUTH_SECURITY + SECRET))
.accessTokenValiditySeconds(env.getProperty(OAUTH_SECURITY + TOKEN_VALIDATION_TIME, Integer.class, 18000));
}
}
@Configuration
@Order(1)
public static class SecurityWebConfiguration extends WebSecurityConfigurerAdapter {
@Inject
private Environment env;
@Inject
private AjaxAuthenticationSuccessHandler ajaxAuthenticationSuccessHandler;
@Inject
private AjaxAuthenticationFailureHandler ajaxAuthenticationFailureHandler;
@Inject
private AjaxLogoutOauthSuccessHandler ajaxLogoutSuccessHandler;
@Inject
private RememberMeServices rememberMeServices;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable().authorizeRequests()
.and()
.formLogin()
.loginProcessingUrl("/api/authentication")
.successHandler(ajaxAuthenticationSuccessHandler)
.failureHandler(ajaxAuthenticationFailureHandler)
.usernameParameter("j_username")
.passwordParameter("j_password")
.permitAll()
.and()
.rememberMe()
.rememberMeServices(rememberMeServices)
.key(env.getProperty("jhipster.security.rememberme.key"))
.and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler)
.deleteCookies("JSESSIONID")
.permitAll()
.and()
.exceptionHandling()
;
}
}
@Order(2)
@Configuration
@EnableResourceServer
public static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Inject
private Http401UnauthorizedEntryPoint authenticationEntryPoint;
@Inject
private AjaxLogoutOauthSuccessHandler ajaxLogoutSuccessHandler;
@Override
public void configure(HttpSecurity http) throws Exception {
ContentNegotiationStrategy contentNegotiationStrategy = http.getSharedObject(ContentNegotiationStrategy.class);
if (contentNegotiationStrategy == null) {
contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
}
MediaTypeRequestMatcher preferredMatcher = new MediaTypeRequestMatcher(contentNegotiationStrategy,
MediaType.APPLICATION_FORM_URLENCODED,
MediaType.APPLICATION_JSON,
MediaType.MULTIPART_FORM_DATA);
http
.authorizeRequests()
.and()
.anonymous()
.disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.httpBasic()
.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.defaultAuthenticationEntryPointFor(authenticationEntryPoint, preferredMatcher)
.and()
.authorizeRequests()
.antMatchers("/api/**").fullyAuthenticated();
}
}
}
For this settings WebSecurityConfigurerAdapter session work correctly. 对于此设置,WebSecurityConfigurerAdapter会话正常工作。 For OAuth after correctly authorizatization i get valid acces token, but for request with this token from session i get this result:
对于正确授权后的OAuth,我获得了有效的访问令牌,但是对于来自会话的带有此令牌的请求,我得到以下结果:
public static String getCurrentLogin() {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
UserDetails springSecurityUser = null;
String userName = null;
if(authentication != null) {
if (authentication.getPrincipal() instanceof UserDetails) {
springSecurityUser = (UserDetails) authentication.getPrincipal();
userName = springSecurityUser.getUsername();
} else if (authentication.getPrincipal() instanceof String) {
userName = (String) authentication.getPrincipal();
}
}
System.out.println(userName); // show anonymousUser
System.out.println(authentication.isAuthenticated()); //show true
System.out.println(authentication.getAuthorities()); //show [ROLE_ANONYMOUS]
System.out.println(userName); //show anonymousUser
return userName;
}
function write in console: anonymousUser true [ROLE_ANONYMOUS] anonymousUser 函数在控制台中写入:anonymousUser true [ROLE_ANONYMOUS] anonymousUser
and should be user1 true [ROLE_USER] user1 并且应该是user1 true [ROLE_USER] user1
The apps git urls: https://github.com/rynkowsw/oauth2 it is oauth2 app https://github.com/rynkowsw/web-and-oauth2-security this is web and oauth2 security app 应用程序git urls: https : //github.com/rynkowsw/oauth2它是oauth2 app https://github.com/rynkowsw/web-and-oauth2-security这是web和oauth2安全应用程序
This app are adapted from jhipster.github.io 这个应用程序改编自jhipster.github.io
to run app you need have postgres db in localhost, like in db resource file: 要运行应用程序,您需要在localhost中拥有postgres db,就像在db资源文件中一样:
driver-class-name: org.postgresql.ds.PGSimpleDataSource
url: jdbc:postgresql://localhost:5432/gymapp
name: gymapp
serverName: localhost:5432
username: postgres
password: jaja
To test app the fastest way is: 要以最快的方式测试应用程序:
http://localhost:8080/oauth/token
headers: Authorization: Basic amhpcHN0ZXJhcHA6bXlTZWNyZXRPQXV0aFNlY3JldA==
this string after basic is combination default jhispter oauth secret and clientid base64 encrypt result 这个字符串基本上是组合默认的jhispter oauth secret和clientid base64加密结果
then 然后
http://localhost:8080/api/account
headers: Authorization: bearer [token from response in first request]
For this same db, result for oauth are: for oauth2 app 对于同一个db,oauth的结果是:for oauth2 app
{
login: "user"
password: null
firstName: "User"
lastName: "User"
email: "user@localhost"
activated: true
langKey: "en"
authorities: [1]
0: "ROLE_USER"
-
}
for web + oauth2 security: 对于web + oauth2安全性:
{
login: "anonymousUser"
password: null
firstName: "Anonymous"
lastName: "User"
email: "anonymous@localhost"
activated: true
langKey: "en"
authorities: [0]
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.