I have a case, where I need to get access token without http call to predefined by Oauth Spring Security /oauth/token endpoint, but instead, have a call for some api, available for the anonymous user, and among the other business data bring the access token back.

I try this code:

        String username = "username";
        String password = "2134";
//
        AccountInitSetting accountSetting = accountService.getInitSetting(username);
        try {
            agentService.createTempCredentials(username, accountSetting.getAccountType(),
                    null, accountSetting.getRoleId(), accountSetting.getGroupId(),
                    ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getHeader("x-forwarded-for"),
                    null, false);
        } catch (UserInterfaceException e) {
            throw new RuntimeException(e);
        }


        Map<String, String> parameters = new HashMap<>();
        parameters.put("grant_type","password");
        parameters.put("username", username);
        parameters.put("password", password);
        parameters.put("scope","all");

        try {
            return tokenEndpoint.postAccessToken(principal, parameters).getBody().getValue();

        } catch (HttpRequestMethodNotSupportedException e) {
            throw new OAuth2Exception(e.getMessage(), e);
        }

    }

please note, that Principal is taken from the @RestController's endpoint method paramether and thus passed to this method.

And I'm getting the below exception:

22:40:33.007 [http-bio-9090-exec-2] ERROR com.openpayment.site.web.service.init.WebServiceExceptionHandler - There is no client authentication. Try adding an appropriate authentication filter.
org.springframework.security.authentication.InsufficientAuthenticationException: There is no client authentication. Try adding an appropriate authentication filter.

What I'm missing?

1

There are 1 best solutions below

0
Eljah On BEST ANSWER

I had to add explicitly new Authentication with isAuthenticated() true and getName() as the application expect.

    String username = "username";
    String password = "2134";
  Map<String, String> parameters = new HashMap<>();
    parameters.put("grant_type","password");
    parameters.put("username", username);
    parameters.put("password", password);
    //parameters.put("clientId","clientId4");
    parameters.put("scope","all");
    Principal principal1 = new Authentication() {
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return null;
        }

        @Override
        public Object getCredentials() {
            return null;
        }

        @Override
        public Object getDetails() {
            return null;
        }

        @Override
        public Object getPrincipal() {
            return null;
        }

        @Override
        public boolean isAuthenticated() {
            return true;
        }

        @Override
        public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {

        }

        @Override
        public String getName() {
            return "clientId4";
        }
    };

    try {
        return tokenEndpoint.postAccessToken(principal1, parameters).getBody().getValue();

    } catch (HttpRequestMethodNotSupportedException e) {
        throw new OAuth2Exception(e.getMessage(), e);
    }

}