Authorization authentication (identity server 4)

Keywords: C# JSON network encoding REST

Difference

OpenId: Authentication: authentication
OAuth: aurarize: authorization

  • Enter the account password, and QQ confirms that the correct account password can be used for login -- > authentication
  • The following check boxes need to be checked (get nickname, avatar, gender) -- > authorization

OpenID

When you need to visit website A, website A requires you to enter your OpenId, you can jump to your OpenId service website, enter your user name and password, and then call back to website A, the authentication is successful.

OAuth2.0  

OAuth is an open network protocol about authorization, which allows users to let third-party applications access the user's resources on a website without providing a user name and password to a third party.

  • After the user opens the client, the client requires the user to grant authorization.
  • The user agrees to authorize the client.
  • The client uses the authorization obtained in the previous step to request a token from the authentication server.
  • After authenticating the client, the authentication server confirms that there is no error and agrees to issue the token.
  • The client uses the token to request resources from the resource server.
  • The resource server confirms that the token is correct and agrees to open the resource to the client.
    The client must be authorized by the user to obtain the token. OAuth2.0 defines four authorization methods:
  • authorization code mode
  • Simplify mode
  • resource owner password credentials
  • client credentials

Openid - (openid connect) is short for OIDC

OpenID Connect is an upgraded version of OpenID, or OIDC for short. It is an open standard released in early 2014. It defines an interoperable way based on OAuth2 to provide user identity authentication. In the OIDC, the application does not need to build different protocols for each client, but can provide one protocol to multiple clients. It also uses the JOSN signature and encryption specification to deliver signed and encrypted information, and uses a simple REST/JSON message flow to implement it. Compared with any previous authentication protocol, developers can easily set Cheng. ==In short, OIDC is an extension of OAuth2.0==

ID Tokens
OpenID Connect Id Token is a signed JSON Web Token (JWT: RFC7519), which contains a set of claim s about the user's identity, such as the user's identity (sub), the identifier of the provider that issued the token (iss), the Client identity that created the identity (aud), the validity period of the token and other relevant context information
Access Tokens
The access token allows access to API resources. The client requests an access token and forwards it to the API. The access token contains information about the client and the user, if any. The API uses this information to authorize access to its data.
UserInfo Endpoint
The OIDC also provides a standard protected resource that contains current user information. UserInfo Endpoint is not part of identity authentication, but provides additional identity information. It provides a set of standardized attributes, such as profile, email, phone and address. A special openidsscope is defined in the OIDC and is required. It contains access to Id token and UserInfo Endpoint.

IdentityServer4

Now emerge in an endless stream of application development. Browser based web applications, based on WeChat official account and small program, based on IOS, Android App, desktop applications and UWP applications based on Windows system, etc., so many applications will bring challenges to application development. We should consider the interaction among applications besides the various applications. The refinement of general modules, in which identity authentication and authorization is an essential part of every application. Nowadays, the Internet is very demanding for information security, so a set of unified identity authentication and authorization is very important.

IdentityServer4 is such a framework. IdentityServer4 is a middleware that implements OpenId Connect and OAuth2.0 protocol for ASP.NET CORE.

JwtBearer certification

HTTP provides a set of standard authentication framework: the server can be used to send a challenge to the client's request, and the client provides authentication credentials according to the challenge. The workflow of query and response is as follows: the server returns 401 (Unauthorized) status code to the client, and adds information on how to verify in the WWW authenticate header, which contains at least one query method. Then the client can add the Authorization header to the request for authentication, and its Value is the authentication credential information.

Bearer authentication (also known as Token authentication) is an HTTP authentication scheme, which contains a security Token called Bearer Token. Therefore, the core of bearer authentication is Token. How to ensure the safety of Token is the top priority. One is to use Https, the other is to encrypt and sign the Token. JWT is a popular Token encoding method.

JWT(Json Web Token)

Json web token (JWT) is a JSON based open standard (RFC 7519) which is implemented to deliver statements between network application environments. The token is designed to be compact and secure, which is especially suitable for single sign on (SSO) scenarios of distributed sites. JWT declaration is generally used to transfer the authenticated user identity information between identity provider and service provider, so as to obtain resources from resource server. It can also add some additional declaration information necessary for other business logic. The token can also be directly used for authentication or encryption.

JWT consists of three parts:

..

https://jwt.io/

Header: it is composed of ALG and typ, alg is the abbreviation of algorithm, typ is the abbreviation of type, and specifies the type of token. This part is encoded with Base64Url.
Payload: it is mainly used to store information, including various declarations, which is also encoded by the base URL.
Signature: sign using the server-side key. To ensure that the Token has not been tampered with.

ASP.NET authorization certification (OWIN, Katana)

ASP.NET

The existing asp.net is a mature and functional runtime and developer programming model. At the same time, the framework has been integrated, and various functional units of different logic are closely coupled in the System.web.dll program set. As a larger. NET Framework update cycle, it is based on years. The development team took several evolutionary steps to use asp.net as a set of pluggable components rather than a single framework.

  1. In order to meet the development requirements of Mvc style, ASP.NET MVC is released as an independent download, which enables the engineering team to deliver updates more frequently.
  2. From dynamic, Web pages produced by the server is transformed into communicating with back-end Web APi through AJAX request. With the release of asp.net MVC, the ASP.NET WEBAPI is built, which does not rely on System.Web.dll, and then does not rely on IIS, including the functions running in the custom host.

    OWIN

    Win defines the standard interface between the. NET Web server and the Web application. The goal of the win interface is to separate the server from the application.

    Katana

    Win implementation for Microsoft Server and framework

    advantage

  • Portable
  • Flexible modular structure
  • Lightweight, high performance, scalable

structure

  • HOST: responsible for the configuration and start-up process of the application, including initializing the win pipeline and running the Server.
  • Server (service): the actual HTTP Server. Listen to HTTP requests, and then send the requests and responses to the win middleware pipeline as a dictionary of the win specification.
  • Middleware (Middleware): middleware is located in service and application quality inspection, used to process requests in the pipeline, and can be any component of custom delegation. For example: Logger,Web API
  • Application: specific application code.

    Owin OAuth

    code implementation

///Start configuration
public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        //Authorization authentication
        ConfigAuth(app, container);
        
        app.UseWebApi(config);
        
    }
    private void ConfigAuth(IAppBuilder app,IContainer container)
    {
        app.CreatePerOwinContext(()=> PatternDbContext.Create());
        app.CreatePerOwinContext<ApplicationRoleManagers>(CreateRoleManager);
        app.CreatePerOwinContext<ApplicationUserManagers>(CreateUserManager);

        OAuthAuthorizationServerOptions option = new OAuthAuthorizationServerOptions()
        {

            AllowInsecureHttp = true,
            AuthenticationMode = AuthenticationMode.Active,

            TokenEndpointPath = new PathString("/token"),//Get access? Token authorization service request address
            AuthorizeEndpointPath = new PathString("/authorize"), //Get authorization service request address
            
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),

            Provider = new OpenAuthorizationServerProvider(), //Access? Token related authorization services
            AuthorizationCodeProvider = new OpenAuthorizationCodeProvider(), //Authorization? Code authorization service
            //Refreshtokenprovider = new openrefreshtokenprovider(), / / refresh_token authorization service
            AccessTokenProvider = new OpenAccessTokenProvider()

        };
        //Enable authorization server to generate token
        app.UseOAuthAuthorizationServer(option);
        //Enable authorization authentication
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
    }
}
public class OpenAuthorizationServerProvider:OAuthAuthorizationServerProvider
{
    /// <summary>
    ///User name and password authorization processing
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
                        var userManager = context.OwinContext.GetUserManager<ApplicationUserManagers>();
            var roleManager = context.OwinContext.GetUserManager<ApplicationRoleManagers>();

            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
            //Query whether the user exists
            var userModel = new UserModel() { UserName = context.UserName, Password = context.Password };
            var user = await userManager.FindAsync(userModel.UserName,userModel.Password);
            if (user==null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect");
                return;
            }
            var IpAddress = context.Request.RemoteIpAddress;
            var db = context.OwinContext.Get<PatternDbContext>();
            var result = db.Set<DeviceAddress>().FirstOrDefault(d => d.Address == IpAddress);

            if (result == null)
            {
                context.SetError("invalid_client", IpAddress + "client is not valid");
                return;

            }
           //Query user role
            var roles = await userManager.GetRolesAsync(user.Id);

            //Assembly user permission and other declaration information
            var identity = new ClaimsIdentity(context.Options.AuthenticationType);
            identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
            identity.AddClaim(new Claim("userName", context.UserName));
            foreach (var role in roles)
            {
                var roleTemp = await roleManager.FindByNameAsync(role);//Get the permission corresponding to the role
                foreach (var permission in roleTemp.Permissions)
                {
                    identity.AddClaim(new Claim("Permission", permission.Info));
                }
                identity.AddClaim(new Claim(ClaimTypes.Role, role));
            }
            //Additional display properties
            var props = new AuthenticationProperties(new Dictionary<string, string>
            {
                //{"as:client_id",context.ClientId??string.Empty },
                {"userName",context.UserName },
                 {"userId",user.Id }
            });

            var ticket = new AuthenticationTicket(identity, props);
            //Verification generation token
            context.Validated(ticket);
        }
}
///Custom authorization
public class MyAuthorizeAttribute:AuthorizeAttribute
{
    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        //Get user object
        IPrincipal principal = actionContext.ControllerContext.RequestContext.Principal;
        if (principal == null)
        {
            var token = actionContext.Request.Headers.Authorization.Parameter;
            using (PatternDbContext db=new PatternDbContext())
            {
                var tokenStr = db.LoginStates.FirstOrDefault(t => t.TokenStr == token);
                if (tokenStr != null)
                {
                    tokenStr.IsOnline = false;
                    tokenStr.LogoutDate = DateTime.Now;
                    db.SaveChanges();
                }
            }

            return false;
        }
        //Get permission statement
        var claims = (principal.Identity as ClaimsIdentity).Claims.Where(d=>d.Type=="Permission").Select(d=>d.Value);
        if (claims != null)
        {
            if((Permission!=null)&&! claims.Contains(Permission,StringComparer.OrdinalIgnoreCase))
            {
                return false;
            }
        }
        else
        {
            return false;
        }

        return base.IsAuthorized(actionContext);
    }
}
   

ASP.NET CORE authentication (IdentityServer4)

Authentication server

    //Register authentication server
    services.AddIdentityServer()
        .AddDeveloperSigningCredential()
        .AddMongoRepository()
        //.AddMongoDbForAspIdentity<ApplicationUser, ApplicationRole>(Configuration)
        .AddClients()
        .AddPersistedGrants()
        .AddIdentityApiResources()
        .AddAspNetIdentity<ApplicationUser>()                
        .AddResourceOwnerValidator<CustomResourceOwnerPasswordValidtor<ApplicationUser,ApplicationRole>>()
        .AddProfileService<CusromProfileService<ApplicationUser>>()
        .AddCorsPolicyService< CorsPolicyService>()              
        ;

Resource service

//Add authentication
services.AddAuthentication(opt =>
{    
    opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    
})
.AddCookie("Cookies")
.AddJwtBearer("Bearer", options =>
{
    options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
    {

        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("secret")),
        ValidateLifetime = true,
    };
    var configUrl = new ConfigurationBuilder().AddJsonFile("host.json", false, true).Build()["urls"];
    //var url = Configuration["urls"];
    options.Authority = configUrl;
    options.RequireHttpsMetadata = false;
    options.Audience = "KnowBaseApi";

});  

MVC client

services.AddAuthentication(options =>
    {
        options.DefaultScheme = "Cookies";
        options.DefaultChallengeScheme = "oidc";
        
    })
    .AddCookie("Cookies",opt=>
    {
        opt.LoginPath = "/Login";
    })
    .AddOpenIdConnect("oidc", options =>
    {
        options.SignInScheme = "Cookies";
        
        options.Authority = "http://10.53.28.168:5010";
        options.RequireHttpsMetadata = false;
        options.CallbackPath = "/home";
        options.ClientId = "AntennaKnowbaseApi";
        options.ClientSecret = "secret";
        options.ResponseType = "code id_token";

        options.SaveTokens = true;
        options.GetClaimsFromUserInfoEndpoint = true;

        options.Scope.Add("api1");
        options.Scope.Add("offline_access");
        options.Scope.Add("profile");

        //options.ClaimActions.MapJsonKey("website", "website");
    });

Posted by Daisatske on Sun, 23 Feb 2020 22:56:24 -0800