I am building a web application using an AngularJS front-end and a Spring Boot REST back-end (they are running on separate servers i.e. port 3000 and port 8443). The back-end is supposed to connect to multiple external services (with separate authentications) and provide endpoints for the front-end to use.
For security, I decided to use Apache Shiro. For simplicity, I will pretend there are just 2 external services (ES1 and ES2).
I have created 2 x AuthorizingRealm
which connect to the respective external services and attempt authentication using the provided tokens.
In the doGetAuthenticationInfo
method, if the login is successful, I return a SimpleAuthenticationInfo
with the principal, credentials and the name of the realm.
In the doGetAuthorizationInfo
method, I check the realm name of the principal and, if it checks out, I return a SimpleAuthorizationInfo
with the role "USER" and a permission (e.g. ES1_permitted).
I also extended the UsernamePasswordToken
class for each realm to separate usage even more (through the supports
method).
In a configuration class, I create a bean for a DefaultWebSecurityManager
that uses my two realms and a bean for the Shiro filter.
I added 4 filters:
- anon
AnonymousFilter
- perm
PermissionsAuthorizationFilter
- es1
ES1Filter
- es2
ES2Filter
My filter chain looks something like:
/api/es1/login -> anon
/api/es1/** -> es1, perms[ES1_permitted]
/api/es2/login -> anon
/api/es2/** -> es2, perms[ES2_permitted]
/** -> anon
Somehow, when I served front-end and back-end from the same server (no CORS), it seemed to work. However, now that CORS is an issue, I can't seem to get this to work as expected.
Is there a simpler way to achieve this complete separation of authentication/authorization? I am willing to switch to Spring Security if it can be done there as well.
PS: I am using the Java API, not configuration files (spring xml or shiro.ini).