1

My web application needs users login in via Facebook, then Facebook will return user's information like: Facebook id, username, email...

Configuration:

@SpringBootApplication
@EnableOAuth2Sso
@RestController
public class SocialApplication extends WebSecurityConfigurerAdapter {

    @RequestMapping("/user")
    public Principal user(Principal principal) {
        return principal;
    }

    public static void main(String[] args) {
        SpringApplication.run(SocialApplication.class, args);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .antMatcher("/**")
                .authorizeRequests()
                .antMatchers("/", "/login/**", "/webjars/**")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .logout().
                logoutSuccessUrl("/")
                .permitAll()
            ;
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**");
        web.ignoring().antMatchers("/static/**");
    }
}

WebController:

@Controller
public class WebController {
    @RequestMapping( value = {"/", "/index"})
    public String index(){
        return "index";
    }
}

JavaScript front end let user login via Facebook:

<body>
        <div class="container unauthenticated">
            With Facebook: <a href="/login">click here</a>
        </div>
        <div class="container authenticated" style="display:none">
            Logged in as: <span id="user"></span>
        </div>
        <div>
            <button id="btnLogout" onClick="logout()" class="btn btn-primary">Logout</button>
        </div>

        <script type="text/javascript">

            $("#btnLogout").hide();

            $.get("/user", function(data) {
                $("#user").html(data.userAuthentication.details.name);
                $(".unauthenticated").hide()
                $(".authenticated").show()
                $("#btnLogout").show();
            });

            var logout = function() {
                $.post("/logout", function() {
                    $("#user").html('');
                    $(".unauthenticated").show();
                    $(".authenticated").hide();
                    $("#btnLogout").hide();
                })

                return true;
            }
        </script>
    </body>

After user login via Facebook if the web app is accessed to url: /user, it will return retsult:

{
    "authorities": [
        {
            "authority": "ROLE_USER"
        }
    ],
    "details": {
        "remoteAddress": "0:0:0:0:0:0:0:1",
        "sessionId": "C7C446FC3169FFDDD68ADA8497F19CFC",
        "tokenValue": "EAASZB5Q8S4WYBAGHGhX0XzdGfRIAhm1fMZBScqNYcueCEIBcc3ZCQgfjrFsDRk1LioAFEk8XeXZAxFEKHGpE9LJ83hvNJcRZACzvCx2h14z2eCPAnLJ00soZCNw5276QZCJmD5Kg6xK7MrrIZAm5PKIj40fHIPVO33W25fZBrcBdg0ZCZBYo2gXhD2ZC",
        "tokenType": "bearer",
        "decodedDetails": null
    },
    "authenticated": true,
    "userAuthentication": {
        "authorities": [
            {
                "authority": "ROLE_USER"
            }
        ],
        "details": {
            "email": "deng.bunthai@yahoo.com",
            "name": "BunThai Deng",
            "id": "1676389552422181"
        },
        "authenticated": true,
        "principal": "1676389552422181",
        "credentials": "N/A",
        "name": "1676389552422181"
    },
    "principal": "1676389552422181",
    "clientOnly": false,
    "oauth2Request": {
        "clientId": "1335790916526438",
        "scope": [],
        "requestParameters": {},
        "resourceIds": [],
        "authorities": [],
        "approved": true,
        "refresh": false,
        "redirectUri": null,
        "responseTypes": [],
        "extensions": {},
        "refreshTokenRequest": null,
        "grantType": null
    },
    "credentials": "",
    "name": "1676389552422181"
}

The question is how can I access to get email in the principal or session??

PaulNUK
  • 4,774
  • 2
  • 30
  • 58
Spring
  • 831
  • 1
  • 12
  • 42

1 Answers1

1

I've just found a solution of this problem:

@RequestMapping("/user")
public Principal user(Principal principal) {

    Authentication a = SecurityContextHolder.getContext().getAuthentication();
    HashMap data = (HashMap) ((OAuth2Authentication) a).getUserAuthentication().getDetails();
    System.out.println(data.get("email"));

    return principal;
}
Spring
  • 831
  • 1
  • 12
  • 42
  • 1
    I am stuck with same issue. Even converting the principal to OAuth2Authentication results null for me. Do I need to create a custom principal after successfull Authentication ?? – Ashish Awasthi Feb 06 '18 at 01:12
  • You can cast the session by OAuth2Authentication if the session was created by OAuth. For example, user logins via Facebook, Facebook uses OAuth2 to proctect third party application to access user's data. After, the user allowed the third party app, then OAuth2 created session for the app, and we can cast the session by OAuth2Authentication. Onemore, you don't need to do such "create a custom principal after successfull Authentication" – Spring Feb 06 '18 at 07:40