Here is what I'm trying to do: I have an authentication EJB that can grant user a "ticket" (pair of key and token) by validating username and password. Clients should pass the ticket every call to remote EJB and such ticket should be able to be fetched by EJB (method, or interceptor) and EJB/ or interceptor should validate the ticket and determine whether the call is valid or not.
I don't want to add ticket as parameter to each function that requires authentication, and I believe there should be a way to implement this. I've looked through several articles about JAAS custom login module, but still can't find a non-vendor specific way to do this. (And I am trying to avoid vendor specific implementation)
If JAAS can't do the job, is there anything like "header" in EJB?
Couldn't you just use roles to perform this authorization? Instead of granting a ticket to a user, assign him a role.
Then, it's just a matter of using the inbuilt functionality of checking whether a user is in a role or not.
Although I agree with #EdH, i.e. use #RunAs, you can accomplish what you want by adding to the EJB context your token.
Red Hat does something similar here by using the interface EJBClientInterceptor.
By looking the code of ReceiverInterceptor (which implements the EJBClientInterceptor) you can see how to modify the EJB context (on the client-side) and add your token:
context.setReceiverInvocationContext(new
EJBReceiverInvocationContext(context, receiverContext));
context.sendRequest();
Related
We are using Keycloak for SSO purpose, in particular we are able to use the REST API /admin/realms/{realm}/users to get the basic user details in a Keycloak realm, the response we get is UserRepresentation which seems to have provision for realmRoles and clientRoles as well but by default they are not required/false.
We have a new requirement to fetch the roles of all users, I see there are additional API exposed to get these roles: /auth/admin/realms/realm/users/user-id/role-mappings/realm/, but this means firing another request, and if we have 2k users that means 2k more request.
My question is as UserRepresentation also have properties realmRoles and clientRoles but seems to be optional by default, how can I enable these while firing the request /admin/realms/{realm}/users, and avoid additional request to get roles.
I'm afraid that getting the data you need in one request is not possible: just by looking at the source code of getting all users in UsersResource you can see that realmRoles and clientRoles are never populated.
Having that said, there is one thing that you can do - write your own REST Resource by implementing SPI. In fact, in the past I had a similar problem with groups resource and I ended up writing my own resource. In this case you will need to write custom resource with just one method - getting all users with roles. You can just copy-paste current keycloak logic and add extra bits or extend built-in UsersResource. This, however, is not a single bullet - on the long run you will be required to maintain your own code and upgrades to latest keycloak may not be that simple if some interface will change.
Is there a way to verify a multi-tenant environment USER account is enabled or disabled using WS ?
getUserClaimValue
IS the only one I could see !, unfortunately it asks for User credentials !
Cant we do it at admin level ?
Its not even storing into ldap-attributes. How can I get this verified as super-admin.
Claim URI :
http://wso2.org/claims/identity/accountDisabled
Worked out to get the claim as 'ref'.
How to get the value from this 'ref' direct using LDAP with JAVA ?
Any claims which has the pattern http://wso2.org/claims/identity/XXXXX is considered as a special claim. Hence they are ignored by getUserClaimValue (and by setUserClaimValue when setting value).
You'll need to use either getUserClaimValues or getUserClaimValuesForClaims for the above purpose (And setUserClaimValues to set).
Update
Due to the tenant separation model it is not allowed to get claim details by other tenant admins (Even for super tenant admin). In case you really need that, one possible option would be to write a custom admin service extending the org.wso2.carbon.um.ws.service.UserStoreManagerService class (which reflects RemoteUserStoreManagerService) where it will start a tenant flow for the user's tenant, and call super class method to get the claim value.
I am working on a legacy (struts 1.1 running in jdk 1.4 , tomcat 6)application and need advice for implementing user role based security.
A user u1 has a read/view permission while user u2 has write permission on certain action. E.g
Url for user u1 :
http://www.somedomain.com:8080/app?key=12
(It shows the content related with key 12 from DB).
Url for user u2 :
http://www.somedomain.com:8080/app?key=12¬e=some note test
(It basically insert note value in DB for key 12)
Suppose if user u1 who has view rights, come to know the url used by u2, he can insert any malicious value for particular key, which he is not suppose to do.
Even though role based access to struts action class is in place , here the action class used by both users are same and only difference is url parameter.
Now I have to fix this issue, which is spread across thousands of action classes.So adding checking conditions in each and every action class will not be feasible.
I am thinking of writing a filter class which will read user role and allowed request parameter(with possible values like action='save' action='view') from a configuration file.
Are there any alternative solution approach?
your best choice is to modify the action class and implement some check inside called method (you can mixup container role-based permissions)
public void perform(HttpServletRequest request)
{
String note = request.getParameter("note");
if(!request.isUserInRole("writer") && note != null) throw new SecurityException("not allowed");
...
}
Without knowing much about your application, but I would try to apply java declarative security for my role based solution as much as possible.
If it is easy for you to use the java ee declarative security then go for it.
It is simple, flexible and using standards which will give you the safety you request and the ability to port your solution to different java web server providers.
Maybe a url rewriter (apache in front of the web application can help to reorganize); can split the destinations, and for that in your java web server set the url patterns which will expect different user roles for the read/view and update/write grantings permissions.
This will need some few changes to achieve, but you would definitely not need to change your 4k codebase and you will by this reach a clean solution.
Search for e.g. setting up role based security or java declarative security
some reading with demo...
http://www.thecoderscorner.com/team-blog/hosting-servers/17-setting-up-role-based-security-in-tomcat#.Us0eShoeK-Y
I working on Spring MVC app. The app funcionality is accessible through ReST API which jsp containing ajax logic consume. I am using spring security with defined roles (USER, COMPANY, ADMIN). Methods use requestMapping with responseBody such as:
www.app.com/auth/{userId}/request/{requestId}
It, of course, support GET for obtaining resource and POST for its creating or updating.
The problem is that after succesful login with, for example, userId = 1 I want GET request with requestId = 99. But when I run WebDev client for Chrome, I can also access another resource with easy request in format
www.app.com/auth/5/request/{requestId}
So basically, I can access resources, which I am not allowed to see. I hope you got the idea, where I am heading.
My question is - What is the best approach to secure this?
I was thinking about storing logged user Id (Integer) in session and comparing it everytime request for resource is made, but it seems to me that I am pulling the wrong end of rope :)
Thank you for any advice
You should have a look into the Expression-Based Access Control section of the spring security documentation.
Example copied from the documentation:
#PreAuthorize("#contact.name == authentication.name")
public void doSomething(Contact contact) {
..
}
This would check if name of the contact is equal to the name of the currently logged in user.
Using this this feature you can build much more sophisticated access rules than you could do with simple roles. However, this does not exclude using roles. You can still keep roles for basic security checks.
I'd like to know how to combine these two authentication steps :
check the user/password in an LDAP
add principals (roles) found in a DB to the subject.
The LDAP user repository have no idea about application-specific roles and I don't want to manage the passwords in the application DB. So I need both.
JAAS configuration file allows to have additional LoginModules :
<name used by application to refer to this entry> {
<LoginModule> <flag> <LoginModule options>;
<optional additional LoginModules, flags and options>;
};
but I can't find example that explains how I works.
Is it the good method ?
Thanks
=========================================
Here is my answer :
Indeed we can have additional LoginModules. The JAAS configuration file is :
Sample {
com.sun.security.auth.module.LdapLoginModule Requisite
userProvider="ldap://acme.org:389/OU=Users,OU=_ACME,DC=acmegis,DC=acme,DC=org"
authIdentity="{USERNAME}"
userFilter="(userPrincipalName={USERNAME})"
storePass=true
sample.module.SampleLoginModule required debug=true;
};
Here we have two LoginModules :
The Sun's LdapLoginModule that checks user/password,
and mine sample.module.SampleLoginModule that query my db and fills the principals.
The important parameter is storePass=true that asks the LdapLoginModule to store the username and password in the module's shared state. (see http://docs.oracle.com/javase/6/docs/jre/api/security/jaas/spec/com/sun/security/auth/module/LdapLoginModule.html).
So the next LoginModules can get the username passed to the initialize method in the sharedState Map argument. They should have nothing to do in login() and the query in DB to fill the Principales is done in commit() (like Shimi Bandiel said).
I don't use it yet but there is a DatabaseServerLoginModule developed by JBoss (see http://community.jboss.org/wiki/DatabaseServerLoginModule) that supports authentication and role mapping. Used with password-stacking=useFirstPass we should have the answer to my need without write any line-code (but a beautiful JAAS configuration file).
B.R.
You should implement a LoginModule which in the login method you access the LDAP and check username/password and in the commit method you access the DB and fill the principals.
There is no need here to use multiple LoginModule
It is great!
But implement the LoginModule give you more power to customize the way you interact with LDAP server.
I also struggle the same problem as you.
But remember when implement the LoginModule, you should add the role in login() function , not in commit(), otherwise your subjet will not get the principal.