I have a module that can be accessed only by admin, except for a single action that can be accessed by all authenticated users.
Is there a way to reset the credential for that single action? I tried to use null but still get 403 Error. Is listing all actions in security.yml the only solution?
default:
credentials: [ admin ]
public:
credentials: null
Have you try to set en empty array or credential ?
public:
credentials: [ ]
Yes, you'll have to list all of the actions if you want fine grained control on who has access to what.
Or, another way (albeit ugly) is to set the action, which doesn't require any credentials, to is_secure : false and then check if they're authenticated through the action in the controller.
Also, if you want to do by using credentials, then you should set every user to have a default credential. i.e. with a credential called 'user'
Out of interest: how many actions do you have for this module?
EDIT: Also, what happens if you use a ~ instead of null?
You have to write all allowed credentials inside the public action if you want to have it accesible for logged users with all credentials (sf1.4 ad reference)
.. or you can open the action to the whole world:
default:
is_secure: true
myPublicAction:
is_secure: false
Related
what I am trying to do:
I have an app that takes in login credentials: username and password for a user. I have a rest api that internally calls the keycloak REST API: /auth/realms/realmname/protocol/openid-connect/token
and gets the access token for this user.
Now I am building another REST API to access a resource where I want to do the following:
doSomething(accesstoken, data)
{
a) call keycloak API to validate access token and get roles.
b) if role == manager, process(data)
c) else: return error msg.
}
Now, how do I do (a): validating the access token and getting the roles associated with it.
I know we can do: auth/realms/realmname/protocol/openid-connect/userinfo
but that only gives the details about the user like name, email, etc. but does not display any roles.
Here's an example I got:
{
"name": "test user",
"sub": "e2bad34d-a1a9-4d70-ac84-bd3a3246023e",
"email_verified": false,
"preferred_username": "user",
"given_name": "test",
"family_name": "user"
}
As seen, it doesnt give the roles at all. How do I then tell what roles this access token has? Interestingly, when I search for this, many resources are suggesting the above userinfo endpoint. But this merely tells me taht the access token I provided is valid. Does not give roles for that.
In other words - it authenticates but does not authorize.
Please suggest.
Thanks,
Anand
In Keycloak admin Console, you can configure Mappers under your client. Add a builtin Mapper of type "User Realm Role", then open its configuration e.g. change Token Claim Name if you want.
Client roles can be configured similarly, but they are returned by default in the token under the name resource_access.${client_id}.roles
The the client side you can parse the token to find the roles. E.g. In an angular application and using the keycloak-angular adapter, you can have a the token as a json object by calling keycloak.getKeycloakInstance().tokenParsed.
In a spring boot application and using the Keycloak java api, you can find the roles under the field "otherClaim" in the following class
https://www.keycloak.org/docs-api/10.0/javadocs/org/keycloak/representations/AccessTokenResponse.html
In both representations you will find the roles under the "Token Claim Name" defined in the client mapper configuration
Additionally, if the full scope is not allowed then you need to add the relevant roles to the scope, so they can appear in the token.
After adding role in the roles section , need to move available roles into the Assigned Roles of the scope tab of the respective client section.
I'm trying to login an account in Active Directory with have to change this password (pwdlastset = '0'). The problem I've found is that when this propertie of the entity is enabled, the ldap method can not authenticate with old password. I'am doing the connection with a ruby client and I need to authenticate the user before send the replace instruction to de unicodePwd to avoid security problems. How can I check old password when I have pwdlastset enabled?
A bit of pseudocode:
ldap_con.new(ldap_params)
auth = ldap_con.auth(login, old_pass) # Fail when pwdlastset eql 0
ldap_con.modify(:dn => dn, :operations => [:replace, "unicodePwd", new_pass]) if auth
If I change the pass without authenticate, someone can change the pass of an account without old credentials.
Thanks!
You can set the pwdLastSet to "-1" and then set the password for the user.
As I recall, these need to be done in two LDAP operations.
-jim
I'm using the "Spring Security Core Plugin" for Grails and am using a simple map in my Config.groovy file to restrict access based on authentication type.
For example, I want to prevent users from going to the "user/create" page because obviously you wouldn't want people to be able to create other users when they're logged in (I'm ignoring for now that managers/mods would be able to have this functionality). To accomlish this, I have
grails.plugins.springsecurity.interceptUrlMap = [
'/user/create': ['IS_AUTHENTICATED_ANONYMOUSLY']
]
The only problem is, it seems to be acting like the action:
redirect uri: SpringSecurityUtils.securityConfig.successHandler.defaultTargetUrl
I want it to redirect to the page it was previously on though.
i.e. user/list, attempt to call action create from user controller, if logged in, would reidirect back to user/list.
Any help is GREATLY appreciated.
I might be wrong, but I don't think you can do what you want using ['IS_AUTHENTICATED_ANONYMOUSLY'], it won't restrict logged in user since per documentation
The token accepts any authentication, even anonymous.
Why not just put something like
//in user controller
def create() {
if(springSecurityService.currentUser) {
//let them know they're already logged in
flash.message = message(code: 'your.....message')
redirect(action: "list")
}
//else take them to create form
...
}
Also change 'IS_AUTHENTICATED_ANONYMOUSLY' to 'permitAll'. and use the if statement.
is possible to deny a credential in security.yml?
For example:
default:
is_secure: true
credentials: admin
(i want that user have not the admin credential)
No, it is not possible. All you can do is add all the other credentials to the security file with a OR connector or add some php code in the actions.class.php.
Your best option is extending the sfBasicSecurityUser class, overriding the hasCredential() method to handle it (for example by adding a ! before the given credential). This is what the security filter uses to check if the user may access the requested action.
Then edit your app's myUser class to extend this new class, and voila.
I use symfony sfDoctrineGuardPlugin to manage authentication for both frontend users and backend users. It's fine, except that I don't want frontend users to be able to login to the backend app. I can setup credentials, but credentials are checked after a user gets authenticated. What I want is to have sigin in form to never validate for a user, that is not in a backend group. How can I do this?
I think I found a better solution. sfDoctrineGuard plugin has its own post validator that checks for an optional callable for user retrival.
//app.yml
all:
sf_guard_plugin:
retrieve_by_username_callable: sfGuardUser::getForBackend
//sfGuardUser.class.php
public static function getForBackend($username)
{
$query = Doctrine::getTable('sfGuardUser')->createQuery('u')
->leftJoin('u.Groups g')
->leftJoin('g.Permissions p')
->where('u.username = ? OR u.email_address = ?', array($username, $username))
->addWhere('u.is_active = ?', true)
->addWhere('p.name = ?', 'backend');
return $query->fetchOne();
}
Here's one idea: You could try creating a custom post-validator for the login form. Here's a Google result:
http://www.symfony-project.org/blog/2008/09/05/call-the-expert-how-to-implement-a-conditional-validator
In this validator, you could check whether the user belongs to the group in question and then throw an error accordingly. The user would not get authenticated.
I think you just have to add:
storage:
class: sfSessionStorage
param:
session_name: sf_backend
at the end of your backend/config/factories.yml
By default, symfony shares session cookies, with this solution, symfony separate this cookies.