Spring security OAuth2 身份验证和表单登录在一个应用程序中 [英] Spring security OAuth2 authentication and form login in one app

查看:55
本文介绍了Spring security OAuth2 身份验证和表单登录在一个应用程序中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在一个应用程序中通过 login basic 和 oauth2 将授权和身份验证结合起来?

Is it possible to combine authoryzation and authentication by login basic and by oauth2 in one application?

我的项目基于 jhipster 项目,使用简单的 spring 安全会话登录,现在我需要为移动应用程序添加 oauth2 安全性,看起来这是不可能的.

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.

现在我遇到了工作其中之一的情况,如果 WebSecurityConfigurerAdapter 的订单号大于 ResourceServerConfiguration,则 oauth2 可以.这意味着如果 oauth 安全过滤器是第一个.我在stackoverflow中阅读了很多内容并尝试了许多解决方案,例如:Spring 安全 oauth2 和表单登录配置 对我来说这是一个不工作.
现在我知道这与一些安全过滤器冲突有关,但我不知道如何解决它.

Now i have situation when work one of them, oauth2 ok if WebSecurityConfigurerAdapter had bigger order number than ResourceServerConfiguration. That's mean if oauth security filter is first. 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.
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();


    }
}

}

对于此设置,WebSecurityConfigurerAdapter 会话正常工作.对于正确授权后的 OAuth,我得到有效的访问令牌,但对于来自会话的此令牌的请求,我得到以下结果:

For this settings WebSecurityConfigurerAdapter session work correctly. For OAuth after correctly authorizatization i get valid acces token, but for request with this token from session i get this result:

  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

并且应该是 user1真的[ROLE_USER]用户 1

and should be user1 true [ROLE_USER] user1

推荐答案

应用 git url:https://github.com/rynkowsw/oauth2 这是 oauth2 应用https://github.com/rynkowsw/web-and-oauth2-security这是网络和 oauth2 安全应用程序

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

本应用改编自 jhipster.github.io

This app are adapted from jhipster.github.io

要运行应用程序,您需要在本地主机中有 postgres db,就像在 db 资源文件中一样:

to run app you need have postgres db in localhost, like in db resource file:

    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==

basic 后面的这个字符串是默认 jhispter oauth secret 和 clientid base64 加密结果的组合

this string after basic is combination default jhispter oauth secret and clientid base64 encrypt result

然后

  http://localhost:8080/api/account
  headers:  Authorization: bearer [token from response in first request]

对于同一个数据库,oauth 的结果是:对于 oauth2 应用

For this same db, result for oauth are: for oauth2 app

{
 login: "user"
 password: null
 firstName: "User"
 lastName: "User"
 email: "user@localhost"
 activated: true
 langKey: "en"
 authorities: [1]
 0:  "ROLE_USER"
 -
}

对于网络 + oauth2 安全性:

for web + oauth2 security:

 {
  login: "anonymousUser"
  password: null
  firstName: "Anonymous"
  lastName: "User"
  email: "anonymous@localhost"
  activated: true
  langKey: "en"
  authorities: [0]
  }

这篇关于Spring security OAuth2 身份验证和表单登录在一个应用程序中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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