0

I'm using MSAL on the front end (PKCE) and azure-active-directory-spring-boot-starter on the server to provide an entity which represents the logged in user and their claims.

I've built a class which wraps Microsoft's UserPrincipal to provide easy access to well-known claims:

import com.microsoft.azure.spring.autoconfigure.aad.UserPrincipal;
public class MyCustomUser {
    private UserPrincipal userPrincipal;

    public MyCustomUser(UserPrincipal userPrincipal) {
        this.userPrincipal = userPrincipal;
    }

    public String getEmployeeId() {
        return String.valueOf(this.userPrincipal.getClaim("emplid"));
    }
}

I make this available via a helper class

@Component
public class MyAppSecurityContext {
    public MyCustomUser getUser() {
        UserPrincipal principal = (UserPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        return new MyCustomUser(principal);
    }
}

and then use it in my service layer:

@Service
public class AnnouncementServiceImpl implements AnnouncementService {

    @Autowired
    private MyAppSecurityContext securityContext;

    @Override
    public List<Announcement> saveAnnouncement(Announcement announcement) {
        MyCustomUser currentUser = this.securityContext.getUser();
        String empid = currentUser.getEmployeeId();

        return this.announcementRepository.saveAnnouncement(empid, announcement);
    }
}

This works, but it feels wrong. I'd prefer to have MyCustomUser extend UserPrincipal and have getPrincipal() return my custom type (without effectively re-implementing my own UserPrincipal) instead of providing a facade in front of a member object. The problem is that UserPrincipal's constructor expects JWT concerns, which suggests that this isn't the correct approach. Is there another, more appropriate way to model the user for a Spring security project which relies on client-side claims only?

Josh
  • 4,009
  • 2
  • 31
  • 46
  • May I know what you meant by client-side claims in your question? Correct me if I am wrong, you are trying to implement a better way to access the user claims across the application. If so, create a model for the user claims then, try using token handler or HTTP handler to read all the claims and add the data to the model created. This model can be added to the context as an item and can be read/accessed across the project for that context. The other way is to user graph API to get the user info instead of accessing claims. Correct me if this is not what you are looking for. – Dinakar J Dec 23 '20 at 18:21
  • I'm taking the stateless approach [documented here](https://learn.microsoft.com/en-us/java/api/overview/azure/active-directory-spring-boot-starter-readme?view=azure-java-stable#authenticate-stateless-apis-using-aad-app-roles) and trying to leverage MS's work (ie UserPrincipal) as much as possible. My MyCustomUser above does what you suggest, but it feels wrong because it's a wrapper. – Josh Dec 23 '20 at 20:45
  • Hello @Josh Please try posting this issue on https://github.com/Azure/azure-sdk-for-java/issues . – Nishant Dec 29 '20 at 15:20

1 Answers1

0

@Josh.

In azure-active-directory-spring-boot-starter, UserPrincipal is used in AADAuthenticationFilter and AADAppRoleStatelessAuthenticationFilter. Now both of the 2 filters are deprecated.

Could you please use the latest version of azure-spring-boot-starter-active-diectory? Which is 3.7.0, and it works for spring-boot:2.5.0. Since you used UserPrincipal, then you application is a resource server.

Here is the docs: https://github.com/Azure/azure-sdk-for-java/tree/azure-spring-boot-starter-active-directory_3.7.0/sdk/spring/azure-spring-boot-starter-active-directory#accessing-a-resource-server

We have some samples. You current application is similar to:

  1. https://github.com/Azure-Samples/azure-spring-boot-samples/tree/azure-spring-boot_3.6/aad/azure-spring-boot-sample-active-directory-resource-server-by-filter-stateless
  2. https://github.com/Azure-Samples/azure-spring-boot-samples/tree/azure-spring-boot_3.6/aad/azure-spring-boot-sample-active-directory-resource-server-by-filter

But the 2 usage is deprecated, I suggest you to learn the new way:https://github.com/Azure-Samples/azure-spring-boot-samples/tree/azure-spring-boot_3.6/aad/azure-spring-boot-sample-active-directory-resource-server

chenrujun
  • 126
  • 4