无法从Spring引导OAuth 2中的主体对象获取用户详细信息

时间:2017-11-19 04:57:45

标签: java spring-boot oauth-2.0

@RestController
public class AuthenticationController {

    @RequestMapping("/")
    protected Principal login(Principal user) {
        ObjectMapper mapper = new ObjectMapper();

            System.out.println(SecurityContextHolder.getContext().getAuthentication().getPrincipal());
            System.out.println(SecurityContextHolder.getContext().getAuthentication().getDetails());
            System.out.println(SecurityContextHolder.getContext().getAuthentication().getPrincipal());
            System.out.println("testing testing xyz");
        return user;
    }
}

这是我的代码。我尝试了最大可能的方法来获取用户的详细信息。实际上我想要用户的电子邮件,但是当我返回"用户" - 主要对象,它在屏幕上给json。请帮帮我...

添加了弹簧安全配置...如果我发生了任何问题,请通过它并让我知道..我的范围是openid,电子邮件,个人资料

package com.ggktech;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter;
import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

/**
 * Modifying or overriding the default spring boot security.
 */
@Configurable
@EnableWebSecurity
public class OAuthSecurityConfig extends WebSecurityConfigurerAdapter {

    private OAuth2ClientContext oauth2ClientContext;
    private AuthorizationCodeResourceDetails authorizationCodeResourceDetails;
    private ResourceServerProperties resourceServerProperties;

    @Autowired
    public void setOauth2ClientContext(OAuth2ClientContext oauth2ClientContext) {
        this.oauth2ClientContext = oauth2ClientContext;
    }

    @Autowired
    public void setAuthorizationCodeResourceDetails(AuthorizationCodeResourceDetails authorizationCodeResourceDetails) {
        this.authorizationCodeResourceDetails = authorizationCodeResourceDetails;
    }

    @Autowired
    public void setResourceServerProperties(ResourceServerProperties resourceServerProperties) {
        this.resourceServerProperties = resourceServerProperties;
    }

    /* This method is for overriding the default AuthenticationManagerBuilder.
     We can specify how the user details are kept in the application. It may
     be in a database, LDAP or in memory.*/
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        super.configure(auth);
    }

    /* This method is for overriding some configuration of the WebSecurity
     If you want to ignore some request or request patterns then you can
     specify that inside this method.*/
    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }

    /*This method is used for override HttpSecurity of the web Application.
    We can specify our authorization criteria inside this method.*/
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                // Starts authorizing configurations.
                .authorizeRequests()
                // Ignore the "/" and "/index.html"
                .antMatchers("/", "/**.html", "/**.js").permitAll()
                // Authenticate all remaining URLs.
                .anyRequest().fullyAuthenticated()
                .and()
                // Setting the logout URL "/logout" - default logout URL.
                .logout()
                // After successful logout the application will redirect to "/" path.
                .logoutSuccessUrl("/")
                .permitAll()
                .and()
                // Setting the filter for the URL "/google/login".
                .addFilterAt(filter(), BasicAuthenticationFilter.class)
                .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
    }

    /*This method for creating filter for OAuth authentication.*/
    private OAuth2ClientAuthenticationProcessingFilter filter() {
        //Creating the filter for "/google/login" url
        OAuth2ClientAuthenticationProcessingFilter oAuth2Filter = new OAuth2ClientAuthenticationProcessingFilter(
                "/login");

        //Creating the rest template for getting connected with OAuth service.
        //The configuration parameters will inject while creating the bean.
        OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(authorizationCodeResourceDetails,
                oauth2ClientContext);
        oAuth2Filter.setRestTemplate(oAuth2RestTemplate);

        // Setting the token service. It will help for getting the token and
        // user details from the OAuth Service.
        oAuth2Filter.setTokenServices(new UserInfoTokenServices(resourceServerProperties.getUserInfoUri(),
                resourceServerProperties.getClientId()));

        return oAuth2Filter;
    }
}

2 个答案:

答案 0 :(得分:0)

问题是您没有在代码中配置AuthenticationManager @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { super.configure(auth); }

身份验证管理器:

  

尝试验证传递的Authentication对象,如果成功则返回完全填充的Authentication对象(包括授予的权限)。

对于简单的内存验证管理器,您可以执行以下操作;

@Autowired
public void configure(AuthenticationManagerBuilder auth)
        throws Exception {
    auth.inMemoryAuthentication().withUser("user").password("password")
            .roles("USER").and().withUser("hiren").password("hiren")
            .roles("ADMIN");
}

在此之后,您可以在成功验证用户后获得Principal个对象。 您还可以像这样配置自己的身份验证提供程序:

@Override
protected void configure(
  AuthenticationManagerBuilder auth) throws Exception {

    auth.authenticationProvider(customeAuthenticationProvider);
}

this链接对身份验证提供程序配置非常有用

答案 1 :(得分:-1)

您的方法是REST端点,这意味着此函数的参数是序列化数据。您需要反序列化它并从中获取所需的数据。此函数的参数不能为Priciple类型,您发送的位置可能需要在byte[]中发送。然后,您需要将byte[]转换为String,这是一个JSON。然后使用Jackson库,您需要填写user。之后,您可以获得用户的电子邮件。

@RequestMapping("/")
protected Principal login(byte[] data) {
    String inputJSONString = new String(data);
    ObjectMapper mapper = new ObjectMapper();
    Principle user = objectMapper.readValue(inputJSONString, Principle.class);
    //Now you have a setted user object and you can get user's mail from a method like getMail()
    user.getMail();

    System.out.println(SecurityContextHolder.getContext().getAuthentication().getPrincipal());
    System.out.println(SecurityContextHolder.getContext().getAuthentication().getDetails());
    System.out.println(SecurityContextHolder.getContext().getAuthentication().getPrincipal(
    System.out.println("testing testing xyz");
    return user;
}