OWIN OAuth server sample code example - oauth-2.0

I am using the sample code from this OWIN project http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server and I didnt the deploy of the solutions .When I try to get a authorization token from the server I get redirected to the login page and then to the authorize page but when I am clicking on grant the page is not rediretcing me ..Checking the code it is this am I supposed to create the redirect login with access token myself or is there some configuration I am missing here .
If anyone familiar with the project can please let me know.
if (!string.IsNullOrEmpty(Request.Form.Get("submit.Grant")))
{
identity = new ClaimsIdentity(identity.Claims, "Bearer", identity.NameClaimType, identity.RoleClaimType);
foreach (var scope in scopes)
{
identity.AddClaim(new Claim("urn:oauth:scope", scope));
}
authentication.SignIn(identity);

Related

Function to request user claims and token from Identity Server?

What is the best way to retrieve user claims and tokens after logging into identity server?
I have a .Net Core MVC web app. I redirect to an identity server, log in, then redirect back to my web app.
From my app I would then like to request user claims and token from identity server.
Is there a method call to do this?
I have gone through the tutorials and searched around and found libraries (oidc-client-js, oidc.usermanager for javascript that handles this. OidcClient for native c# apps) that handle this behavior, but not for c# web app - so I realize maybe what I'm asking for is not the convention but I'd still appreciate any insight on this.
Edit:
To elaborate, in the c# web app tutorials, specifically tutorial #3, I fail to see how claims and token information become retrievable from from figure 1 to figure 2.
Furthermore, I'm trying to call and handle these objects in c#, not html.
Figure 1
Figure 2
Thank you
In controller , you can retire claims like
var claims = User.Claims;
Get the access token/id token/refresh token :
var accessToken = HttpContext.GetTokenAsync("access_token").Result;
var idToken = HttpContext.GetTokenAsync("id_token").Result;
var refreshToken = HttpContext.GetTokenAsync("refresh_token").Result;
To achieve that , you need register your OIDC middleware inside ConfigureServices as follows (making sure to set SaveTokens to true) :
.AddOpenIdConnect(options => {
// Set all your OIDC options...
// and then set SaveTokens to save tokens to the AuthenticationProperties
options.SaveTokens = true;
});
In mvc razor page , you can get the information :
#using Microsoft.AspNetCore.Authentication
#{
ViewData["Title"] = "Home Page";
}
<dl>
#foreach (var claim in User.Claims)
{
<dt>#claim.Type</dt>
<dd>#claim.Value</dd>
}
</dl>
<dt>access token</dt>
<dd>#await ViewContext.HttpContext.GetTokenAsync("access_token")</dd>
<dt>ID token</dt>
<dd>#await ViewContext.HttpContext.GetTokenAsync("id_token")</dd>
<dt>refresh token</dt>
<dd>#await ViewContext.HttpContext.GetTokenAsync("refresh_token")</dd>

MVC sign in to IdentityServer4 without redirect

So I'm trying to sign in users from my ASP.NET Core 2.2 MVC app without redirecting them to IdentityServer4. So far I'm able to use IS4's ResourceOwnerPassword flow to get a token and get a token with RequestPasswordTokenAsync, but even after I set my client with the access token it's not authenticating my app.
Controller:
public async Task<IActionResult> Login()
{
var client = new HttpClient();
var response = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = "http://localhost:5000/connect/token",
ClientId = "mvc3",
ClientSecret = "secret",
UserName = "LegitUsername",
Password = "VeryLegitamitePassword",
Scope = "api1"
});
client.SetBearerToken(response.AccessToken);
return Redirect("/");
}
Current behavior: Token is granted, but my header still has the "Login" button
Expected behavior: Token is granted, "Logout" button is displayed
The current behavior suggests that I haven't been authenticated even though I'm holding the token. I know I'm missing something to pass the token to the HttpContext to authenticate my app, but can't figure out what. Any help would be appreciated.
Well, you do not log in the user. You request an access token from id4. Normally you request an access token to add it to a request (as you did) to access a resource.
Please refer to the examples: https://github.com/IdentityServer/IdentityServer4.Samples/tree/master/Clients/src
There are several examples implementations for mvc.

Cannot Signout the External Identity provider in IdentityServer

I've an MVC Application which uses IdentityServer4. In IdentityServer4, I registered SAML2 (SustainSys.SAML2) as the external Login provider. and Login works fine.
When user log out of the MVC application, it logs out from the MVC application but the log out for External Login Provider isn't triggering. I checked the LogOut method of my identity Server which does the redirect to External Authentication Scheme. but the redirect doesnt happen.
this triggers a redirect to the external provider for sign-out
return SignOut(new AuthenticationProperties { RedirectUri = url },
vm.ExternalAuthenticationScheme);
And here is the code where in i registered External Identity Provider for SAML. I've used Nuget package from SustainSys SAML.
.AddSaml2(options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.SignOutScheme = IdentityServerConstants.SignoutScheme;
options.SPOptions = CreateSPOptions();
var idp = new IdentityProvider(new EntityId(_strIDPEntityId), options.SPOptions)
{
AllowUnsolicitedAuthnResponse = true,
Binding = Saml2BindingType.HttpRedirect,
SingleSignOnServiceUrl = new Uri(_strSingleSignOnURL),
SingleLogoutServiceBinding = Saml2BindingType.HttpRedirect,
SingleLogoutServiceUrl = new Uri("https://devit-dev.onelogin.com/trust/saml2/http-redirect/slo/1111")
};
idp.SigningKeys.AddConfiguredKey(
new X509Certificate2(
AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "../../../App_Data/OneLogin.cer"));
options.IdentityProviders.Add(idp);
});
Not sure what am i missing here. Appreciate any help.
Check your logs, it should show you the decision process that ends up in a local logout. There are A LOT of things that need to be in place for a federated logout to work. You need a service certificate and you need some special claims. The latter will be simplified in a future compatibility release with Sustainsys.Saml2/IdSrv4

Identity Server 4 with EF identity DB - OpenID Connect Failing

PLEASE NOTE: This issue was not resolved in this post. I was asked to create a new post. Please refer to the new post titled:
Identity Server 4 with EF identity DB - OpenID Connect Failing (1)
I have an Identity Server 4 solution with EF Identity DB. I can login with my email and external gmail account, but when I try to login using OpenID (User name and Password) I receive the error below. The issue maybe with the info stored in the Identity DB tables. I'm new to Identity Server and this is my first attempt working with EF Identity DB. I can post DB info if it helps resolve the issue.
Source code:
https://github.com/gotnetdude/GotNetDude-PublicRepository/tree/master/AuthServer
Identity Server Log File:
https://github.com/gotnetdude/GotNetDude-PublicRepository/blob/master/AuthServer_log.txt
MVC Client Log:
https://github.com/gotnetdude/GotNetDude-PublicRepository/blob/master/MVCClient_log.txt
Any suggestions would be appreciated. Paul
EDIT
Please find below the Client configuration info from the identity tables. I'm not sure where to set the AllowedRedirectUris in the DB. The other question I have is why does it work when I sign-in with my email account?
Here is the AuthServer Startup code where I add oidc mvc client as the challenge option ("OpenID Connect") which is fail. The MVC client works fine if I login with the email credentials. I guess is that this has some to do with the way the scope is being handled on the mvc client. Any suggestion are appreciated.
services.AddAuthentication()
.AddGoogle("Google", options =>
{
options.ClientId = "434483408261-55tc8n0cs4ff1fe21ea8df2o443v2iuc.apps.googleusercontent.com";
options.ClientSecret = "3gcoTrEDPPJ0ukn_aYYT6PWo";
})
.AddOpenIdConnect("oidc", "OpenID Connect", options =>
{
//options.Authority = "https://demo.identityserver.io/";
//options.ClientId = "implicit";
//options.SaveTokens = true;
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.SaveTokens = true;
options.ClientId = "mvc";
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
});
I'm trying to connect to authority (:5000) from the MVC Client (:5002) see image below:
Debug results from AccountService:
There are 3 instances IdentityServer4.EntityFramework.Entities.Client in the client store under context, clients. All 3 instances had there EnableLocalLogin set to True. I hit the break point after selecting OpenID Connect option.
I also set a breakpoint at the top of the login controller, which it never reached:
I think the problem is in line 74 from AuthServer/Startup:
.AddOpenIdConnect("oidc", "OpenID Connect", options =>
{
...
options.ClientId = "mvc";
...
});
The server is not the mvc client. I think this is 'confusing' IdentityServer. You don't need to add oidc to the server. If you remove theses lines then it should work.
If you login from the mvc client website (:5002) then you should be redirected. And if you login to IdentityServer (:5000) you don't have to be redirected. The server is the authority, the resource is identified by a scope and the client by a clientid.
Check the Log files that you have provided. The error that you are receiving is
Invalid redirect_uri: http://localhost:5000/signin-oidc.
If you check your client configuration your AllowedRedirectUris contains http://localhost:5002/signin-oidc.
You have a (typo) mistake in the port. It must be 5002.
EDIT
According to your screenshots, and to the log files, your client is properly configured on the Identity Server side. The problem is in your MVC client, not in the database. You need to look there, and find what RedirectUrl you are setting when starting the client itself.
EDIT 2:
OK, after looking at your code I realized that what #Ruard van Elburg is telling you is the reason for having this problem. When using the Internal authentication, you don't need to specify it like this (you are really confusing Identity Server). This specification is for external Oidc provider only (for example Okta, or whatever else Oidc provider you have). Check here. You see - the Identity Server Startup.cs doesn't contain this code that you have (line 74 to 89 here). Why don't we do this step by step. Try with removing the lines that I mentioned.

401 when authenticating an OAuth 2.0 bearer token with Microsoft Azure Active Directory in an MVC API

I'm writing an API service in MVC (no views, just API), and I want to use OAuth 2.0 tokens acquired via the client_credentials flow (2-legged OAuth). I created an ActiveDirectory app in the Azure management portal, and have successfully acquired a bearer token (see screenshot from Postman at the bottom).
Then I installed the Microsoft.Owin.Security.ActiveDirectory nuget package, created an Owin startup class and wrote the following code in it:
public class OwinStartup
{
public void Configuration(IAppBuilder app)
{
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
var myoptions = new WindowsAzureActiveDirectoryBearerAuthenticationOptions();
myoptions.Audience = // my App ID
myoptions.Tenant = // my tenant
myoptions.AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive;
app.UseWindowsAzureActiveDirectoryBearerAuthentication(myoptions);
}
}
I added a controller with an action, and I would like the action to be accessible with the bearer token.
This is the controller:
public class TestController : Controller
{
[Authorize]
public JsonResult Index()
{
return Json(3, JsonRequestBehavior.AllowGet);
}
}
I'm trying to call it with the Authorization header like this:
However, I'm getting 401: "You do not have permission to view this directory or page". The details are:
Module ManagedPipelineHandler
Notification ExecuteRequestHandler
Handler System.Web.Mvc.MvcHandler
Error Code 0x00000000
Requested URL http://localhost:57872/test
Logon Method Anonymous
Logon User Anonymous
It looks that my bearer token is ignored.
What am I doing wrong?
Appendix: Creating an Azure Active Directory OAuth bearer token in Postman with the client_credentials flow:
It seems that I can get it to work by creating a second application in AD - a client app, authorizing it to the service app, and requesting the authentication token as the client rather than as the service.
So in the token request I had to use the client app's ID and secret instead of the original ones and add another parameter: "resource", whose value is the service app ID: https://mytenant.onmicrosoft.com/servieappname
I based my solution on this good example by Microsoft. Replaced the Windows store app by a web app acting as the client.
I added the following attribute to the controller directing it to use the specific
authentication filter.
[HostAuthentication("Bearer")]
public class someController:ApiController{
}
Change your TestController so it derives from ApiController instead of Controller.

Resources