Grails spring security grails.plugins.springsecurity.providerNames - grails

Lets say that i would like to utilize two authentication provider for the same login request.
grails.plugins.springsecurity.providerNames = [
'customAuthenticationProvider',
'ldapAuthProvider',
'anonymousAuthenticationProvider',
'rememberMeAuthenticationProvider']
The scenario is that i first get authenticated with my customAuthenticationProvider, which grants/deny access. When this is done, it moves on to check if it is able to authenticate the user towards an LDAP server which in its turn grant/deny.
Is this the way that spring security will operate given for example the list of providerNames above? Or will it grant access if the first provider access/deny and behave accordingly.
Does all authentication attempts need to pass in order to be granted access?

The providers will be tried in the order listed until one authenticates successfully, or they all fail. When one authenticates, the process stops, and the remaining providers will not be tried.

Related

Keycloak - Permissions & Policy only works when using Evaluate tab

Our team is looking to use Policies/Permissions in Keycloak to grant scopes to a user when they log in, but only if they have a specific role.
I've gone through a couple tutorials and was successful in setting it up and testing it using the Evaluate tab (under Authorization). If my user has the specified role in my policy, the scope shows up in the token. When I remove the role, the scope does not show up.
That's all great. Our problem is that it doesn't work when I make an authentication code flow call using the same client (i.e. not using the evaluate tab). I never get any authorization section in my token at all...this only appears when I use the Evaluate tab.
I'll note that I've tried auth code flow calls requesting the scope as well as requesting the resource and also not requesting them. Same result...no authorization section at all in the generated token.
Am I missing something on how this functionality is supposed to work? Where could my gap be? TIA!
The token you obtain in the Evaluate tab is not an access token, it's an authorization token that Keycloak will issue to clients when they ask for permissions.
The access token you obtain via the authorization code flow will not contain permissions.
When using Keycloak Authorization Services, your clients will obtain permissions by requesting an authorization token from the Authorization REST API (cf: https://www.keycloak.org/docs/latest/authorization_services/#_service_obtaining_permissions)
You can do that manually or instead use a policy enforcer which is integrated in the Keycloak adapters :
Spring Boot : https://www.keycloak.org/docs/latest/securing_apps/#_spring_boot_adapter
Javascript : https://www.keycloak.org/docs/latest/authorization_services/#_enforcer_js_adapter
Quarkus : https://quarkus.io/guides/security-keycloak-authorization
etc..
There are lots of examples of what you want to achieve in the keycloak quickstart github repo. (folders starting by app-authz-*).
The spring boot adapter is not able to authorize the scope based resource policies correctly and there seems to be a bug.
Where as evaluate on admin UI does evaluate the scope based policies correctly.
I kind of hacked to get it working by creating different resources for each individual scope and then assigning policies. But thats not what it should be.

spring security role-based needed for full stack app?

I am implementing a basic login app. here are the features:
Upon successful login, there should be a welcome page that shows the name, username and role (manager/user).
If the user has a manager role, the welcome page will have a link to access a restricted webpage.
This restricted webpage can only be accessed by a manager role and not by other user roles.
implement logout functionality.
If the userid or password is not valid, I should remain at the login page with an error message "Invalid userid or password".
All data should be stored in a database.
The application should demonstrate MVC pattern...
my schema:
enter image description here
i am using react js for the front end. i build the backend using spring security with the role-based authorization where certain url can be accessed by certain role. i already do a testing on backend end using postman where i try to access /restricted and it responded with 401 if i use ROLE-USER instead of ROLE-MANAGER by using the mvcMatchers(). now the confusing part is the frontend
i noticed i can do all the necessary validation on the front end. i dont even need to do mvcMatcher() on the backend as i can just load the userdetails and roles and ask react to validate for me! hell, i dont even need to use role-based authorisation. i just need to add extra field in user table named "role" and use that to check for item 3 and display the role on item 1. i just need 1 table, not 3. i can even ask react to redirect to /login if user is trying to access /welcome without login, or disable /unauthorised if user role is USER.
but i dont feel right about this way. i'm confused.
a. whats the best approach?
b. is role-based only applicable to rest-api services, not full stack app? from what i see front end can do ALL validation
back end repo
front end repo
a. The Best approach is to have authorization at the back-end level because your React front-end is not the only way to access the back-end. If the back-end doesn't have authorization implemented, then even if you have validation on the front-end, a malicious user can use any other HTTP client to access the back-end without authorization.
b. Role-based authorization is applicable in all scenarios in which you want to allow access to resources based on user roles, no matter which stack is used.

How to add additional custom criteria for authorization or token creation in Spring Oauth?

We have implemented Spring Oauth authorization+resource server that can be used for external applications.
Now we would like to add custom checks before some oauth calls returns in the authorization server, most importantly for the authorization code but also before allowing returning a token sometimes.
An example use case might be that which users that are allowed to login for a specific client_id might vary and if not allowed this should generate a redirect back with an error.
So for example a user might trigger a login from a third-party app, redirected to our authorization server and shown a login page, however after login it is discovered (through our business logic) that this specific user is not allowed to authorize access to that specific app/client id.
What is the best way to achive this result in a way that is consistent error handling in Spring oauth?
Also, a related question is also how to resolve the client details before the login screen shown so more specific client details can be shown when logging in?
We could parse the client_id parameter manually but maybe there is a more elegant way to hook into Spring oauth to solve this?
(sorry for dual question but its sort of related and the first question is the most important one)

Spring security based application having both form login and SSO

I have searched enough but I haven't got a clear answer and thus posting this question.
I have an existing application which uses spring security for authentication.
Current implementation uses a custom implementation of UsernamePasswordAuthenticationFilter for doing this.
Thus the flow is something like below(in very simple terms):
inputrequest>DelegatingFilterProxy>LoginUrlAuthenticationEntryPoint>CustomUsernamePasswordAuthenticationFilter>AuthenticationManager>CustomAuthenticationProvider
Now I have a requirement to implement SSO (since the user is already asusmed to be authenticated) in some scenarios.
The requirement states that if I have a specific request parameter present then I need to automatically authenticate the request without bothering about user/password.
So it is same set of resources and I do not have to authenticate user/password if the specific SSO related request parameter is present.
e.g
suppose a resource \test\bus is a secure resource.
if I come from normal way then we need to check if the user is authenticated or nor and force user to put valid user/password
if I come from SSO channel then I need to show the \test\bus resource as the user is already authenticated.
currently all the access restrictions are put through <http> element
e.g the snippet of security-config.xml is as follows:
Query: What options do I have in this case. I can think of below options:
Pre-authenticate the user before spring security framework kicks in. This will mean creating an authentication token and putting in spring context before spring security filter is called. This can be done through another filter which is called before spring security filter chain. I have tested it and it works.
Create another custom security filter which set-up the authentication token. I am not clear if this is correct approach as not sure when do we create multiple custom security filter
Create another custom authentication provider e.g SSOCustomAuthenticationProvider. This provider will be called in the existing current flow as we can have multiple authentication providers to a authentication manager. The only issue is that in order to achieve this I have to change the request url to authentication filter's target url so that spring security doesn't check for authentication.
to explain more,
let's say request uri is /test/bus, I will write a filter which will intercept the request and change it to /test/startlogin. This is currently my CustomUsernamePasswordAuthenticationFilter's target url i.e
<property name="filterProcessesUrl" value="/test/startlogin"/>
The flow will be
inputrequest>DelegatingFilterProxy>LoginUrlAuthenticationEntryPoint>CustomUsernamePasswordAuthenticationFilter>AuthenticationManager>SSOCustomAuthenticationProvider
I have tested this and this works. Is this a valid approach or a hack.
Is there any other viable option available with me.
Thanks for reading this.

Using a Custom Single Sign On Authentication Service with Spring Security Core Plugin

I'm working on a Grails application and want to integrate with a custom single-sign-on service (not CAS, but similar). I'm struggling to find all the pieces that I need to customize to make this happen. Can someone explain to me a general outline as to what I need to use to accomplish this? I've read the documentation on the plugin, but it assumes I know which beans to override and where to put all the needed files.
I've block-quoted what I think needs to be done based on my research below each point.
Order of Operations
1- The user requests secure content (everything is secure in the application for now)
I believe this setting is in the Config.groovy file:
grails.plugins.springsecurity.rejectIfNoRule = true
grails.plugins.springsecurity.securityConfigType = "InterceptUrlMap"
grails.plugins.springsecurity.interceptUrlMap = [
'/**':['ROLE_ADMIN']
]
2- Spring Security checks to see if the user has a specific value set in a cookie provided by the authentication service
I'm guessing I need to create an authentication filter, but I don't know where to put it or what it should look like.
If they don't, the user is redirected to this custom SSO service, they login, once authenticated, the user is redirected back to my application (with a new cookie set)
3- Spring security checks for the cookie value and validates it against the custom service (via HTTP POST)
From some research, I think that I need to use PreAuthenticatedProcessingFilter, but I haven't been able to find any examples of how to do this.
4- The custom service returns a series of name/value pairs, a user then needs to be created in the local application database (or the timestamp of "lastLoggedIn" is updated if they user's data is already in the database)
I believe this is done in the same PreAuthenticatedProcessingFilter as number 3 or in a GrailsUserDetailsService
5- The user's authentication is cached in the session for a period of time (6-8 hours) so that re-validation against the SSO service doesn't need to occur every time the user requests a new resource.
I'm not sure if this is something that's done inherently or if I need to add code to do this (and also set the session timeout)

Resources