Shiro custom realm restrict simple auth to certain users - shiro

I'm using Shiro and have a custom realm. My app has many users in a database, and I also want to support non-user process accounts for API access. In my realm, I have implemented:
public boolean supports(AuthenticationToken at)
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)
This works great, we have a login form and process the UN/Password no problem.
I want to allow certain users to be able to use basic HTTP auth, and the rest to use form auth that is already working. I can set the INI to allow either method but I don't see how to implement a check for the type of authentication used in the realm.
If I get a login attempt for a non-api user authenticated via HTTP headers, I want to reject the request.
How do I do this, write a filter and check for the HTTP header is the only way I can think of.

I did the following to make this work:
Add an "api" role to certain users
Create another Application class and set its ApplicationPath to /api for the REST endpoints I wanted to expose
Restricted the /api path to authcBasic, role[api] in the shiro.ini file
This works great. Here are details: http://blog.mikeski.net/blog_post/470

Related

Keycloak: How can user be filtered for a specific OIDC client by role?

We have one realm with many users and multiple OIDC clients configured. We would like to connect another application (OIDC Client) to the realm. Unfortunately, the client cannot check for any attributes or roles to be present.
How can I configure Keycloak to authenticate with a specific OIDC-client but return failing authentication if users have not a specific role?
Generally this type of option will not work, since authorization redirects occur before you know who the user is, and therefore before you know which roles are involved.
WHAT I WOULD DO
Make an authorization redirect perform only the following job:
Signing in the user and returning the user id (sub claim), along with perhaps a couple of scopes
Then manage roles within your app - the second app should call a Web API that does this:
Get claims from the access token, and also from other sources, then use them for identification and authorization
If a user authenticates but is not entitled to use a particular app, detect this via an API call, then present an Access Denied page in the app after login.
To reach this you should implement the AuthenticatorFactory and Authenticator interfaces of Keycloak. Look here for more infos.
In the authenticate() method you will write something similar to this:
If(client == yourClient){
// Check for roles
}
Otherwise, expected behaviour in case of failure.

Restrict front client connexion with groups / roles in a realm

I'm looking for a way to restrict user access to specific clients in a realm.
I know I can do it with client where Authorization is enabled (fine-grained authorization support) but it doesn't work when trying to connect from front (client need to be public and not confidential).
I'm using a javascript application to login from front-end.
Is there a way to enable Authorization for public client or a work around ?
Thanks.
I'm not sure if this will totally answer your question because it's still not specific enougth but it may give you some further help.
In case you're new to the topic, please see difference between public and confidential clients here.
The current best practice for public clients like HTML/Javascipt applications is to use OpenId Connect with the Authorization Code Flow + PKCE. HTTPS is of course a must have. I recommend you use a javascript openid connect adapter for this like the following for example:
https://github.com/panva/node-openid-client
Basically your authentication / authorization flow is shown here:
When the user wants to login from your frontend client application first a unique verifier is generated which is only available to the exact user / browser session. This value get's hashed as a code challege. Then the user gets redirected to the login page of your authorization server (Keycloak for example) passing some parameters like a redirect uri and the challenge.
With successful login the user get's a session at the keycloak server which also stores the hashed challenge. Then the user gets redirected to given redirect uri (a path in your application) together with a code to obtain an access token. Back in your application you application uses the original value together with the code to get the actual token. The authorization server ckecks the value against the stored challenge and geturns the access token if it matches. You see the extra verifier is to prevent that anybody compromises your code fragment to obtain a token on your behalf.
Now you have an encoded access token in your browser app. Note the token itself is normally only encoded not encrypted but it can be signed. Those signatures can later be used from your backend to ckeck the token integrity but we will come to that soon. Roles, claimes, scopes and so on included in your access token tell you the privileges of the user/identity. You can of course use them to enable/disable functions in your app, block routes etc. but in the end client protection is never really effective so your real authorization ande resource protection happens at your resource server which is your backend (node, .net core, java etc.) maybe a restful Web Api. You pass your access token as a part of the http request header with every request to the backend. Now your backend checks the token integrity (optional) expiration time etc. analyzes scopes, claimes and roles to restrict the resource access.
For example a simple GET myapi/car/{1} may only need a token or can even be annonymous while a POST myapi/cars or PUT myapi/car/{1} may need a special role or higher privileges.
Does that help you out?

angular2 login page for a web client to a back-end REST service

I am writing an Angular2 client web application client as a front end for a REST services providing access to some resources.
The REST service is protected with basic HTTP auth, and allows unauthenticated access for some of its endpoints (for instance GET /freeresource), while requires user/password authentication for other endpoints (say GET /protectedresource, or POST /freeresource, etc.).
For my Angular2 client, I would like to implement a loging page allowing access to the web application with the same ":" accepted by REST service. For this I'm following this tutorial : https://medium.com/#blacksonic86/angular-2-authentication-revisited-611bf7373bf9#.myifbz656
The problem is that the above tutorial assumes that the backend REST service has an explicit /login endpoint returning an authentication token to which you post your credentials, while my REST service does not have such an endpoint, but just returns an authorization error when passed missing or wrong credentials for endpoints that require them. I didn't find any alternative article or tutorial for a situation like this.
What is the correct way of proceeding in such a case? I could "simulate" the /login endpoint by accessing for instance a protected resource with username and password read from the app login page and trying to access a protected resource GET /protectedresource, considering as a failed login if this call returns an unauthorized error, but clearly this is not a satisfying solution (what today is a protected resource could become freely accessible tomorrow, for instance), so what is a "clean" way to implement the web app login in this case?
You don't need to simulate the /login endpoint. You just need to know on the client accessing which resource requires authentication. You can implement the same "CanActivate" method from the tutorial, and write your service call to pass credentials (or use the local storage if the user is authenticated already) when you make the REST call. If your REST endpoints require authentication every time, get them from the user at the login page, store them in the local storage, then pass them to the endpoints that need authentication.

How can I use [Authorize] in IndentityServer3 within the IdentityServer itself?

I've set up an IdentityServer3 server with IdentityManager and MembershipReboot and have successfully managed to implement Bearer authentication across a few different ASP.NET Web API servers and a couple of Angular JS clients.
I'd like to be able to set up an endpoint on the IdentityServer3 Web API project itself that users can go to in order to edit their email-addresses, password, etc. In order to do this, I need to be able to use the [Authorize] attribute inside one of the controllers running on the IdentityServer3 server. I'm having trouble trying to find out how to do this.
In projects that use my IdentityServer3 server, I simply add something like:
app.UseIdentityServerBearerTokenAuthentication(...);
I wondered if I could just do the same in the server itself, but it wouldn't be Bearer token authentication in this case.
I just want to add an MVC page to the auth server that I can redirect to from the client applications to allow the user to modify their details. How can I achieve this?
There's an OWIN Context Environment extension in IdentityServer3, namely GetIdentityServerFullLoginAsync, which retrieves the logged in user (stored in a cookie).
I can create a new Action that uses this to retrieve the logged in user and display their details. I can also add endpoints for updating the password, etc, so long as I protect against CSRF in the usual MVC way.

Sencha touch 2 oauth2 authentication

Using OAuth 2 I need to limit user access to permitted resources only, where the connection to the API is made through an ext.js REST proxy. The ext.js proxy takes care of data retrieval and maintaining the model relationships. I haven't found an elegant way to make different calls from the proxy to the backend depending on the user logged in.
I am wondering if the proxy has to be different for each user logged in to my application because each user has their own access token.
Another option would be to make the proxy know about the logged in user during the proxy initialisation process and save this information in a persistent way.
Has anyone solved a similar situation before?
The article gives a detailed explanation on how to use OAuth2 with Sencha Touch.
http://www.sencha.com/blog/meetcha-using-sencha-touch-to-build-a-mobile-app-for-meetup-com/
There are several ways to use OAuth. One uses redirects after the initial authentication (for this you might use an iFrame inside a Sencha login view). The other uses your backend server as an intermediary to the OAuth server that can avoid the iFrame solution but requires more logic on your server.
You can then use a session cookie which will be resent with all HTTP requests including your REST calls. Most back ends support session cookies and so all you need to do then is look up the user ID you stored in the session object as part of your REST API code.
Another option is to set a custom HTTP header in each REST call that requires authentication. To avoid duplicate code, create a derived class from the Sencha proxy class to set the header containing the access token. You can store the access token in a Store or on the Application object or as a static value on the proxy. I've done this for both REST proxy calls and Sencha Direct proxy calls.
AJAX Proxy header property:
http://docs.sencha.com/touch/2.3.1/#!/api/Ext.data.proxy.Ajax-cfg-headers