How to access authenticated user in other than Authentication Controller in Grails? - authentication

I am using Authentication 2.0.1 spring security plugin to authenticate my web services . I am in success to login and set user session through Authentication Service . I also get sessionUserand isLoggedIn in success response in Authentication controller. But same thing I am not able to access from other controller.Please have a look into my code , I am not able to access authentication service in other than authentication controller , Please help.Thank in advance.
class ModuleController {
def authenticationService
def beforeInterceptor = [action: this.&auth]
private auth() {
println 'checking authentication in module controller : '+authenticationService.isLoggedIn(request)
}
}

Related

I am receiving status 401 Unauthorized when I attempt to call my secured API by keycloak

I have an web application providing an REST API endpoints, secured with spring security and SSO Keycloak.
My web application works fine with protection on and I can access REST API endpoints using web browser, after authentication on keycloak and redirect back to endpoint. I am getting expected JSON response, which mean user and role should be configured correctly.
But when i want to call a provided REST API endpoint from another web application or using Postman, i have every time an error 401 error: unauthorized.
In the header of the request I am putting:
"Authorization": "Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgO...." token.
I am able to fetch this token from keycloak in consumer web application and also when I am making a request using postman.
My Keycloak configuration in my spring security config:
#KeycloakConfiguration
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
/**
* Registers the KeycloakAuthenticationProvider with the authentication manager.
*/
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
/**
* Defines the session authentication strategy.
*/
#Bean
#Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.authorizeRequests()
.antMatchers("/api/v1/**").hasRole("USER")
.antMatchers("/admin/**", "/app/**").hasRole("ADMIN")
.anyRequest().permitAll();
}
}
My keycloak.json file:
{
"realm": "realm-name",
"auth-server-url": "https://auth.server.com/auth/",
"ssl-required": "external",
"resource": "resource-name",
"verify-token-audience": true,
"credentials": {
"secret": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
},
"use-resource-role-mappings": true,
"confidential-port": 0
}
My method in the controller of the api:
#RestController
#RequestMapping("/api/v1")
public class WakeMeUpController {
#RequestMapping(value = "/test", method = RequestMethod.GET, produces = MediaType.TEXT_PLAIN_VALUE)
public String testMeUp() {
return "I am tested!";
}
}
This is a part of my client configuration in keycloak:
keycloak Client screen
Rest keycloak config is how it is coming by default.
Thx for your help!
Thank you. The problem was into audience configuration in keycloak.
For a client, you need to configure new Mapping under Client -> <client_name> -> Mappers and add another Mapping with mapper type 'Audience' and appropriate 'Included Client audience' (i choose client id i have used to make request)
Also another problem that i have faced after i solve this one, was that user was authenticated but was forbidden the access to endpoint.
Explicitly adding role into client configuration itself and assigning this role to the user solve it and it is working.
From huge help was setting spring logging to DEBUG
logging.level.org.springframework.security=DEBUG
And also XXX-Authentication header in server response that gives better description what the issue is.

Blazor Server / Asp.Net Core: Http Request doesn't pass user identity to MVC Controller when published on IIS

currently I'm having trouble getting identity information in my MVC controllers. It's no problem when debugging the blazor application locally but when I publish the application on IIS, I only get the identity of the executing service account, for instance "MachineName\ApplicationPoolIdentity" or "MachineName\LocalService" (depending on what was selected as identity in the application pool settings) in my MVC controllers. On the Blazor pages, however, authentication and authorization seems to work fine.
I got "Windows Authentication" enabled and "Anonymous Authentication" disabled in IIS site authentication settings.
I need the users identity for our audit trail implementation, which creates an entry for each crud operation.
In the MVC Controller I tried using "this.User.Identity" or "HttpContext.User.Identity", which is the same object. When debugging locally it shows the corect identity (of myself as caller). When deployed on IIS I get "MachineName\ApplicationPoolIdentity"
the MVC controller looks as such:
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class DatabaseSystemsController : CustomControllerBase
{
// GET: api/DatabaseSystems
[HttpGet("/api/AllDatabaseSystems")]
public async Task<ActionResult<IEnumerable<DatabaseSystem>>> GetAllDatabaseSystems()
{
try
{
var identity = HttpContext.User.Identity
...
return await _context.DatabaseSystems.ToListAsync();
}
catch (Exception)
{
...
}
}
}
I hope someone can help.
Thanks in advance
L.
To get the user to impersonate use the AuthenticationStateProvider and get the user from this and cast to a WindowsIdentity to retrieve the AccessToken.
This works in both a controller and a razor component.
Inject the AuthenticationStateProvider and then in your method use the following code:
var authState = await _authenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
var userToImpersonate = (WindowsIdentity)user.Identity;
await WindowsIdentity.RunImpersonatedAsync(userToImpersonate.AccessToken, async () =>
{
// Your Code in here to call your api
}

Asp.net mvc web use both token base authentication and form authentication

I have an asp.net mvc project that contains some web API controllers.my mvc area and pages are authenticated via form authentication.
API controllers should be consumed from native android client I need to register deice and authenticate them for some API's. I searched and seen some web api example used token authentication but here how can i merged both token and form authentication for different request?
how can i customize my security configuration to generate token and authenticate api requests?
here is Startup.Auth class:
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager> (ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
// Configure the sign in cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
// Enables the application to remember the second login verification factor such as phone or email.
// Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
// This is similar to the RememberMe option when you log in.
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
}

Authenticating and Authorizing using ADFS WS-Fed protocol

I am working on implementing Authenticating and Authorization in my application.
For Authentication:
I configured by ADFS Server with WS-Fed Sign in Protocol and enabled JWT. Created MVC application and configured to use WS-Fed for authenticating user.
Now question here is how do I store JWT token in my cookie after successfully login?
Here is my code
public partial class Startup
{
private static string realm = ConfigurationManager.AppSettings["ida:Wtrealm"];
private static string adfsMetadata = ConfigurationManager.AppSettings["ida:ADFSMetadata"];
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions{ CookieName="JwtToken",CookieHttpOnly=false});
app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
Wtrealm = realm,
MetadataAddress = adfsMetadata
});
}
}
For Authorization
I have a separate Web API project. I want to authorize my api's by passing the JWT token in header of every request but not sure how to extract JWT token from cookie and pass it to web api for validating.
I found the answer here http://www.software-architects.com/devblog/2015/02/02/ADFS-and-ADAL-Lab.
ADAL (Active Directory Authentication Libraryfor .NET and for JavaScript) which can be used to acquire token in mvc application and pass the token in header for authorizing web api.

unauthorizedRedirect set to false, still redirecting

I'm writing some REST api for my cake 3.0 application, and I need to set $this->Auth->unauthorizedRedirect to false, as the manual says that this would prevent my application to redirect to login url for unauthorized requests.
http://api.cakephp.org/3.0/class-Cake.Auth.BasicAuthenticate.html
The problem is that I'm trying to set it in my Users controller, and it doesn't work:
class UsersController extends AppController {
public function initialize() {
parent::initialize();
$this->loadComponent('RequestHandler');
}
public function beforeFilter(Event $event) {
parent::beforeFilter($event);
$this->Auth->allow(['logout']);
// Change the authentication mode when using REST api
if(! $this->RequestHandler->accepts('html')) {
$this->Auth->unauthorizedRedirect = false;
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
}
}
}
This scripts works fine as detecting if a user is actually registered, but fails when I try to use wrong authentication data, showing the login form instead of throwing an error. What am I doing wrong?
Authentication and authorization are two different things
You are mixing up authentication and authorization, that's two different things. Logging in a user is authentication, testing whether a logged in user is allowed to access a specific action is authorization.
So the unauthorized redirect configuration applies to logged in users when accessing actions.
Handling unauthenticated requests
What you are looking for, ie throw an exception on unauthenticated requests, is done by the basic authentication adapter by default, so I assume that you actually aren't using this adapter!?
So if you are using a different adapter, this behavior is best implemented in either your controller where you are trying to identify the user
$user = $this->Auth->identify();
if (!$user) {
throw new ForbiddenException('Stop! Hammer time!');
} else {
$this->Auth->setUser($user);
}
or, in case you want the exception to be thrown for every controller, in a custom authentication adapters unauthorized() method, which is being invoked on unauthenticated requests before executing possible redirects. Quote from the docs:
Cookbook > Authentication > Handling Unauthenticated Requests
When an unauthenticated user tries to access a protected page first the unauthenticated() method of the last authenticator in the chain is called. The authenticate object can handle sending response or redirection by returning a response object, to indicate no further action is necessary. Due to this, the order in which you specify the authentication provider in authenticate config matters.
If authenticator returns null, AuthComponent redirects user to login action. [...]
Here's a simple example that extends the form authentication handler:
src/Auth/MyCustomAuthenticate.php
namespace App\Auth;
use Cake\Auth\FormAuthenticate;
use Cake\Network\Exception\ForbiddenException;
use Cake\Network\Request;
use Cake\Network\Response;
class MyCustomAuthenticate extends FormAuthenticate
{
public function unauthenticated(Request $request, Response $response)
{
if(!$request->accepts('text/html')) {
throw new ForbiddenException('Ah ah ah! You didn\'t say the magic word!');
}
}
}
Controller
$this->loadComponent('Auth', [
'authenticate' => [
'MyCustom'
]
]);
See also
Cookbook > Authentication > Creating Custom Authentication Objects
Cookbook > Authentication > Using Custom Authentication Objects