zoukankan      html  css  js  c++  java
  • mvc webapi 授权demo

    参考资料

    https://www.cnblogs.com/Leo_wl/p/4919783.html

    https://msdn.microsoft.com/zh-cn/library/microsoft.aspnet.identity.entityframework(v=vs.111).aspx

    https://www.cnblogs.com/xsj1989/p/5287375.html

    image

    <connectionStrings>
       <!--<add name="DefaultConnection" connectionString="Data Source=(LocalDb)MSSQLLocalDB;AttachDbFilename=|DataDirectory|aspnet-WebAPIDemo_UserLogin-20180327033757.mdf;Initial Catalog=aspnet-WebAPIDemo_UserLogin-20180327033757;Integrated Security=True"
         providerName="System.Data.SqlClient" />-->
       <add name="DefaultConnection" connectionString="Data Source=.SQL2008R2;User Id=sa;password=sa2008;Initial Catalog=AspNet_Identity;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
    </connectionStrings>

    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using Microsoft.AspNet.Identity.Owin;
    using Microsoft.Owin;
    using Microsoft.Owin.Security;
    using Microsoft.Owin.Security.Cookies;
    using Microsoft.Owin.Security.Infrastructure;
    using Microsoft.Owin.Security.OAuth;
    using Owin;
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Linq;
    using System.Security.Claims;
    using System.Threading.Tasks;
    using System.Web;
    using System.Web.Http;
    using WebAPIDemo.Models;

    //[assembly: OwinStartup(typeof(WebAPIDemo.Startup))]//删除Global.asax
    namespace WebAPIDemo
    {
         public class Startup
         {
             public void Configuration(IAppBuilder app)//using Owin;
             {
                 //var config = new HttpConfiguration();
                 //WebApiConfig.Register(config);
                 ConfigureOAuth(app);

                //这一行代码必须放在ConfiureOAuth(app)之后
                 //app.UseWebApi(config);
             }
             public void ConfigureOAuth(IAppBuilder app)
             {
                 OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()//using Microsoft.Owin.Security.OAuth
                 {
                     AllowInsecureHttp = true,//允许客户端一http协议请求;
                     TokenEndpointPath = new PathString("/token"),//using Microsoft.Owin; //token请求的地址,即http://localhost:端口号/token;
                     AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(180),
                     Provider = new SimpleAuthorizationServerProvider(),//提供具体的认证策略
                     //refresh token provider
                     RefreshTokenProvider = new SimpleRefreshTokenProvider()
                 };
                 // 使应用程序可以使用不记名令牌来验证用户身份
                 //app.UseOAuthBearerTokens(OAuthOptions);//using Microsoft.AspNet.Identity.Owin
                 // Token Generation
                 app.UseOAuthAuthorizationServer(OAuthServerOptions);
                 app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
             }
         }


    //开始 数据库操作EF CodeFirst生成数据库
    public class AuthContext : IdentityDbContext<IdentityUser>
    {
         public AuthContext() : base("DefaultConnection")
         {

        }
         public DbSet<RefreshToken> RefreshTokens { get; set; }
    }

    public class AuthRepository : IDisposable
    {
         private AuthContext _ctx;

        private UserManager<IdentityUser> _userManager;

        public AuthRepository()
         {
             _ctx = new AuthContext();
             _userManager = new UserManager<IdentityUser>(new UserStore<IdentityUser>(_ctx));
         }
         //注册用户
         public async Task<IdentityResult> RegisterUser(RegisterModel userModel)
         {
             IdentityUser user = new IdentityUser
             {
                 UserName = userModel.UserName
             };

            var result = await _userManager.CreateAsync(user, userModel.Password);

            return result;
         }
         //查询用户
         public async Task<IdentityUser> FindUser(string userName, string password)
         {
             IdentityUser user = await _userManager.FindAsync(userName, password);

            return user;
         }
         public async Task<bool> AddRefreshToken(RefreshToken token)
         {

            var existingToken = _ctx.RefreshTokens.SingleOrDefault(r => r.Subject == token.Subject);

            if (existingToken != null)
             {
                 var result = await RemoveRefreshToken(existingToken);
             }

            _ctx.RefreshTokens.Add(token);

            return await _ctx.SaveChangesAsync() > 0;
         }

        public async Task<bool> RemoveRefreshToken(int refreshTokenId)
         {
             var refreshToken = await _ctx.RefreshTokens.FindAsync(refreshTokenId);

            if (refreshToken != null)
             {
                 _ctx.RefreshTokens.Remove(refreshToken);
                 return await _ctx.SaveChangesAsync() > 0;
             }

            return false;
         }

        public async Task<bool> RemoveRefreshToken(RefreshToken refreshToken)
         {
             _ctx.RefreshTokens.Remove(refreshToken);
             return await _ctx.SaveChangesAsync() > 0;
         }

        public async Task<RefreshToken> FindRefreshToken(int refreshTokenId)
         {
             var refreshToken = await _ctx.RefreshTokens.FindAsync(refreshTokenId);

            return refreshToken;
         }
         public void Dispose()
         {
             _ctx.Dispose();
             _userManager.Dispose();
         }
    }
    //结束 数据库操作
    //开始 token验证和刷新


    public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
    {
         public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
         {
             context.Validated();
             return Task.FromResult<object>(null);

    }

            public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
             {
                 using (AuthRepository _repo = new AuthRepository())
                 {
                     IdentityUser user = await _repo.FindUser(context.UserName, context.Password);

                    if (user == null)
                     {
                         context.SetError("invalid_grant", "用户名或密码不正确.");
                         return;
                     }
                 }

                var identity = new ClaimsIdentity(context.Options.AuthenticationType);
                 identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
                 identity.AddClaim(new Claim(ClaimTypes.Role, "user"));
                 identity.AddClaim(new Claim("sub", context.UserName));

                var props = new AuthenticationProperties(new Dictionary<string, string>
                 {
                     {
                         "as:client_id", context.ClientId ?? string.Empty
                     },
                     {
                         "userName", context.UserName
                     }
                 });

                var ticket = new AuthenticationTicket(identity, props);
                 context.Validated(ticket);
             }

            public override Task TokenEndpoint(OAuthTokenEndpointContext context)
             {
                 foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
                 {
                     context.AdditionalResponseParameters.Add(property.Key, property.Value);
                 }

    return Task.FromResult<object>(null);


         }
    }


         public class SimpleRefreshTokenProvider : IAuthenticationTokenProvider
         {
             public async Task CreateAsync(AuthenticationTokenCreateContext context)
             {
                 var refreshTokenId = Guid.NewGuid().ToString("n");

                using (AuthRepository _repo = new AuthRepository())
                 {

                    var token = new RefreshToken()
                     {
                         Id = refreshTokenId.GetHashCode(),
                         Subject = context.Ticket.Identity.Name,
                         IssuedUtc = DateTime.UtcNow,
                         ExpiresUtc = DateTime.UtcNow.AddMinutes(30)
                     };

                    context.Ticket.Properties.IssuedUtc = token.IssuedUtc;
                     context.Ticket.Properties.ExpiresUtc = token.ExpiresUtc;

                    token.ProtectedTicket = context.SerializeTicket();

                    var result = await _repo.AddRefreshToken(token);

                    if (result)
                     {
                         context.SetToken(refreshTokenId);
                     }

                }
             }

            public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
             {

                int hashedTokenId = context.Token.GetHashCode();

                using (AuthRepository _repo = new AuthRepository())
                 {
                     var refreshToken = await _repo.FindRefreshToken(hashedTokenId);

                    if (refreshToken != null)
                     {
                         //Get protectedTicket from refreshToken class
                         context.DeserializeTicket(refreshToken.ProtectedTicket);
                         var result = await _repo.RemoveRefreshToken(hashedTokenId);
                     }
                 }
             }

            public void Create(AuthenticationTokenCreateContext context)
             {
                 throw new NotImplementedException();
             }

            public void Receive(AuthenticationTokenReceiveContext context)
             {
                 throw new NotImplementedException();
             }

        }
         public class RefreshToken
         {
             public int Id { get; set; }
             public string Subject { get; set; }
             public DateTime IssuedUtc { get; set; }
             public DateTime ExpiresUtc { get; set; }
             public string ProtectedTicket { get; set; }
         };
         //结束 token验证和刷新
    }
    //测试postman
    //注册http://localhost:37351/api/account/Register body-raw-json
    //{
    //"UserName":"fingal@qq.com",
    //"Password":"123456*",
    //"ConfirmPassword":"123456*"
    //}
    //token http://localhost:37351/token body-x-www-form-urlencoded-key-value
    //grant_type:password
    //userName:fingal@qq.com
    //password:123456*





    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.Owin;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Threading.Tasks;
    using System.Web.Http;
    using WebAPIDemo.Models;

    namespace WebAPIDemo.Controllers
    {
         //[EnableCors(origins: "*", headers: "*", methods: "*")]
         //[Authorize(Users = "Alice,Bob")]//特殊用户限制
         //[Authorize(Roles = "Administrators")]//角色限制
         [Authorize]
         [RoutePrefix("api/Account")]//http://localhost:38627/api/account/register
         public class AccountController : ApiController
         {
             AuthRepository auth = new AuthRepository();
             // POST api/Account/Register
             [AllowAnonymous]
             [Route("Register")]
             public async Task<IHttpActionResult> Register(RegisterModel model)
             {
                 if (!ModelState.IsValid)
                 {
                     return BadRequest(ModelState);
                 }

                IdentityResult result = await auth.RegisterUser(model);

                if (!result.Succeeded)
                 {
                     return GetErrorResult(result);
                 }

                return Ok();
             }
             private IHttpActionResult GetErrorResult(IdentityResult result)
             {
                 if (result == null)
                 {
                     return InternalServerError();
                 }

                if (!result.Succeeded)
                 {
                     if (result.Errors != null)
                     {
                         foreach (string error in result.Errors)
                         {
                             ModelState.AddModelError("", error);
                         }
                     }

                    if (ModelState.IsValid)
                     {
                         // 没有可发送的 ModelState 错误,因此仅返回空 BadRequest。
                         return BadRequest();
                     }

                    return BadRequest(ModelState);
                 }

                return null;
             }
             // GET api/Account/UserInfo
             //[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
             [Route("UserInfo")]
             public string GetUserInfo()
             {
                 return User.Identity.GetUserName();
             }
             [Authorize]
             [Route("")]
             public List<Order> Get()
             {
                 return Order.CreateOrders();
             }
         }
    }

  • 相关阅读:
    SQL SERVER 查看sql语句性能与执行时间
    SQL SERVER 一组数据按规律横着放置,少则补空,如人员按一进一出的规律,进出为一组,缺少的补null
    SQL SERVER 子查询使用Order By;按In排序
    SQL SERVER 字符拆分列为多行
    SQL SERVER 字符合并多行为一列
    SQL SERVER pivot(行转列),unpivot(列转行)
    ASP.NET ViewState详解
    数字签名
    ASP.NET Form身份验证方式详解
    细说进程、应用程序域与上下文之间的关系
  • 原文地址:https://www.cnblogs.com/fingal/p/8682853.html
Copyright © 2011-2022 走看看