I'm a newbie for ASPnet identity services and we require a following requirement.
Following is the architecture setup
1. Appserver
Appsever having
a. Entity Framework
b. ASP.Net Web API2 Odata services
c. Authorization server
2. Webserver
ASP.Net MVC 5 application (Client which access the App server)
The flow needs to be
MVC5 Cleint application having a login / Register form
While register / login the information needs to send to the authorization server int he app server, Authorize and creating the claims using Identity Services.
Once the Identity has been created in the Authorization server, the client application should logged in
I'm aware of getting bearer token from authentication server and that will be used as header information to access the API service
All we are lacking is the MVC client application should use the same identity claims that have created in the Authorization server.
Is there any way to access the claims which are created in the auth server.
I have got some samples about how to authenticate in the auth server and receiving token though OWIN and from this token we can access the API securely but I need of the client web application needs to sign in based on the token
I have gone through the following links
http://blogs.msdn.com/b/webdev/archive/2013/09/20/understanding-security-features-in-spa-template.aspx
Also, I require to add claims when ever it requires after login as well
I have resolve this issue as follows, but I'm not sure this is the effective method
Once log-in and retrieve the bearer token (this token should assigned with claims identity already such as username, role .. etc)
In the web api AccountController, need to create a method to retrieve the default claims which requires for client web application. Please check the follows
[Authorize]
[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
[Route("UserInfo")]
public UserInfoViewModel GetUserInfo()
{
var firstname = ((ClaimsIdentity)User.Identity).Claims.Where(c => c.Type.Equals("FirstName")).SingleOrDefault();
var lastname = ((ClaimsIdentity)User.Identity).Claims.Where(c => c.Type.Equals("LastName")).SingleOrDefault();
var IsApproved = ((ClaimsIdentity)User.Identity).Claims.Where(c => c.Type.Equals("IsApproved")).SingleOrDefault();
var userinfo = new UserInfoViewModel
{
UserName = User.Identity.GetUserName(),
FirstName = firstname.Value.ToString(),
LastName = lastname.Value.ToString(),
UserApproved = Convert.ToBoolean(IsApproved.Value.ToString()),
HasRegistered = externalLogin == null,
LoginProvider = externalLogin != null ? externalLogin.LoginProvider : null
};
return userinfo;
}
From the client, this actin will be called through the token as a header.
Once we have got the information (is in Json string format) needs to serialize with the UserInfoViewModel class (user defined viewmodel is based on the info we require and send from webapi account) with javascript serializer
Using these viewmodel information, assign them to local storage and using (cookies for my case) as a identity at local
keep logout webapi too when ever you logs out from web app.
Please let me know if you need more info or code
Related
I have been asked to create a 'Authentication/Authorization' Middle man or broker as an http,MVC web application, so that this can be used to multiple applications on our organization for authentication/Authorization purposes. Means, users will signup, Login on this broker application and once confirmed Authenticated, authorized user, he will get redirected to client applications accordingly. This is the use case.
I am choosing OAuth and OWIN to develop this broker in an MVC applicaiton, which means OAuth(Authorization) will issue access token + refresh token, once user is successfully authenticated. I use normal, simple, minimal authentication logic inside the Oauth Authorization Server's Login Controller as below :
public class AccountController : Controller
{
public ActionResult Login()
{
var authentication = HttpContext.GetOwinContext().Authentication;
if (Request.HttpMethod == "POST")
{
var isPersistent = !string.IsNullOrEmpty(Request.Form.Get("isPersistent"));
if (!string.IsNullOrEmpty(Request.Form.Get("submit.Signin")))
{
var user = Constants.Users.UserCollection.Where(u => u.Email.ToLower() == Request.Form["username"].ToLower().Trim() && u.Password == Request.Form["password"].Trim());
if (user.Count() > 0)
{
authentication.SignIn(
new AuthenticationProperties { IsPersistent = isPersistent },
new ClaimsIdentity(new[]
{ new Claim(ClaimsIdentity.DefaultNameClaimType, Request.Form["username"]),
new Claim("DisplayName", user.FirstOrDefault().DisplayName) } , "Application"));
}
}
}
return View();
}
This is the MSFT sample application I am following to develop this conceptual application.
https://learn.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server.
My question here is : I read in many articles like, its not good to use Oauth authentication, else use OPENID Connect handling authentication. To be frank, I am not used with OPENID Connect and I am not sure about the necessity of creating a OPENID Provider for my organization, Since this service will be used only by customers of our organization - less than 200,000 users. We hardly need a user signup and login, this account need to be used among different web applications of our organization. Please help me here with your inputs. Thanks in advance.
I think your question is about the benefits of OpenID Connect (OIDC) over OAuth 2.0.
OIDC builds upon OAuth 2.0 so you can use all of it's features. In a practical context, the question you should ask yourself is: Do other applications (clients, APIs), which use your "broker" (authorization server/security token service/OpenID provider) need to know something about the user, who just logged in? Do they need the ID, it's roles, username etc..? If the answer is no and you just need a signed token you are probably better of with OAuth.
If you start to include user claims (=attributes) in your access token you should at least have a look at OIDC. Also note, that even if you include claims in your access token, these are meant for the resource server (=API) and are normaly inaccessable for the client (unless you extract them and expose them on the API side - this is basically what the OIDC userinfo endpoint does).
We have a scenario where we have a single application that will be accessed from our organization and also accessed from a outside organization. We will be hosting this web application in azure. I am using MVC 5 with the Owin WSFederation Middleware. I can connect to my Local ADFS Server and it works as expected.
app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
Wtrealm = "https://localhost:44321/",
MetadataAddress = "https://sso2.xxxxx.com/FederationMetadata/2007-06/FederationMetadata.xml"
});
When I use ACS as the Main STS and set up our ADFS server as an IDP, it routes to the correct ADFS login page, but once I authenticate I get this error
ID4037: The key needed to verify the signature could not be resolved from the following security key identifier 'SecurityKeyIdentifier
(
IsReadOnly = False,
Count = 1,
Clause[0] = X509RawDataKeyIdentifierClause(RawData = MIIC4DCCAc...'. Ensure that the SecurityTokenResolver is populated with the required key.
app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
Wtrealm = "https://localhost:44321/",
MetadataAddress = "https://xxxxxxxx.accesscontrol.windows.net/FederationMetadata/2007-06/FederationMetadata.xml"
});
I feel like this is an issue because the Federated metadata contains the key for the signature and since the owin middleware only has the metadata from the ACS the signer can't be determined.
Thoughts?
Is the realm configured in ACS?
If I was implementing this, then i would probably use ADFS instead of ACS for my Home Realm Discovery because ACS is on it's way out.
I would configure Azure as an additional Claims provider in ADFS and only have my application using ADFS.
You also get a little more control around what the HRD pages look like.
Secure 2 different web applications with one identify service
Identity Service: Thinktecture Identity Service V2
Application 1: Asp.net MVC 5 application
Application 2: Asp.net Web API application
The above Applcation 1 and Application 2 are different projects and hosted in different servers. Now my scenarios are
1. Want to secure Application 1 with Identity Service.
2. Want to secure Application 2 with Identity Service.
Use case 1: If user access Application 1 it should redirect to identity service login page, once I entered the credentials and login in to application 1, the same token allow me to access Application 2.
Use case 2: If user try to access any API from Application 2 without login into Identity service, the request should reject.
I found a way to do this using pure SAML tokens. The trick is you need to create a delegation account in Identity Server to allow your web app to delegate identity to a specific realm (where your service lives). Then in the web app you make a service call using the the token that the user already has to get a new token which you use to access your service.
I asked a very similar question and answered it myself here.
Ok. I did eactly the same thing just now. Everything required to get that done is written here. If you're using IdentityServer, you need to configure the Token Type of your RP to be JWT:
this allows you to later extract the token from your authenticated MVC 5 application (see the link above to see how to do this) and then send that token to your Web API. You then need to tell you web api to accept that token, using Microsoft's JwtSecurityTokenHandler class. This class has a ValidateToken() method which accepts 2 parameters, the first being the access token that you put into your auth headers of the requests to the Web API, and the second, the validation parameters are basically what you've defined in IdentityServer's config:
validationParams = new TokenValidationParameters
{
AllowedAudiences = _allowedAudiencesAndSigningKeys.Select(x => x.Key),
ValidIssuer = ConfigurationManager.AppSettings["IssuerIdentity"],
ValidateIssuer = true,
SigningTokens = _allowedAudiencesAndSigningKeys.Select(x => new BinarySecretSecurityToken(Convert.FromBase64String(x.Value)))
};
The Audience(s)/Realm(s) you want to allow access to, the issuer name (your Identity Server name) and the signing symmetric key(s) of the applications you have defined in Identity Server and want to grand access to. The ValidateToken() method returns an ClaimsPrincipal with a list of the claims extracted from the token. The code to do all this can be put in a message handler:
public static void Configure(HttpConfiguration config)
{
var authNConfig = new AuthenticationConfiguration();
config.MessageHandlers.Add(new MyTokenValidationHandler());
}
I have a working site aaa.com with custom membership provider
connected as http module.
I need a create OAuth 2.0 Authorization
Server + Resource Server
Main scenario of using is Authorization
Code Grant.
Here is a good example of creating what I need http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server (see source code of example)
What is my problem:
I want to bind Authorization Server to subdomain of main site -
oauth.aaa.com and when user came from external site to my
Authorization Server, this server check if user is already
authenticated on main site(aaa.com) and if yes - he must just press
Grant button and allow external site access, if no - he must enter user name and password and after this he must automatically be log in
to main site and Authorization Server must be authenticated too.
I've already connected my custom membership provider as http
module(another variant of using not impossible now) to Authorization
Server and Authorize action of this server is already authenticated
when user already logged in to main site.
I don't understand how I must configure Authorization Server(or create some customizations) that it can accept a cookie from main
site(or automatically synchronize and create a new cookie for
Authorization Server using info from already authenticated request).
I was try to configure CookieAuthenticationOptions with same cookie name as cookie name of main site and check that in cookie of main site domain is .aaa.com ...but nothing happend and variable ticket in code = null
var authentication = HttpContext.GetOwinContext().Authentication;
var ticket = authentication.AuthenticateAsync(Auth.AuthenticationType).Result;
Or may be I need another library, not based on OWIN? I saw DotNetOpenAuth library but seems its OAuth client, not server.
I have build a OAuth2.0 Authorization server using dotnetopenauth that will manage authentication, authorization, and assign accessToken to the caller. The caller will use the access token to access the api (webservices) at resource server.
If follow the sample provided by dotnetopenauth in Resource Server, api that builded using WCF can be authenticated by OAuthAuthorizationManager
If using ServiceStack to build my api in Resource Server, how to build the authentication process that verify the incoming api request based on assigned OAuth2.0 access token? The functionality should similar to OAuthAuthorizationManager in the dotnetopenid sample and not based on login session.
Just some update
I didn't use the AuthenticateAttribute or RequiredRoleAttribute from ServiceStack.ServiceInterface.
I create 2 custom RequestFilterAttribute to replace the functions provided by AuthenticateAttribute and RequiredRoleAttribute.
In each custom RequestFilterAttribute's Execute method, I'm using method in dotnetopenauth to verify the access token.
//httpReq==req from Execute(IHttpRequest req, IHttpResponse res, object requestDto)
The code for the access token verification as following, reference the relevant documentation from both servicestack and dotnetopenauth for more info. ResourceServer is class from dotnetopenauth
HttpRequestBase reqBase = new HttpRequestWrapper((System.Web.HttpRequest)httpReq.OriginalRequest);
var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(AuthorizationServerPublicKey, ResourceServerPrivateKey));
IPrincipal ip = null;
resourceServer.VerifyAccess(reqBase, out ip);
If the ip is null then not authenticated, if not null, the incoming request is valid and can use the ip to check the role e.g. ip.IsInRole(requiredRole)
I'm not sure this is the correct way to do the checking or not, but it's works for me. Any better solution are welcome.