13

के साथ पहला प्रमाणीकरण भ्रम मुझे मौजूदा MySQL डेटाबेस के लिए एक वेब एपीआई सी # एप्लिकेशन बनाने की आवश्यकता है। मैंने प्रत्येक डेटाबेस तालिका को एक विश्वसनीय API (जो CRUD संचालन की अनुमति देता है) पर बाध्य करने के लिए एंटीटी फ्रेमवर्क 6 का उपयोग करने में कामयाब रहा है।डीबी- एएसपी.NET वेब एपीआई 2 + ईएफ 6

मैं लॉगिन/पंजीकरण प्रणाली लागू करना चाहता हूं (ताकि मैं भविष्य में भूमिकाएं और अनुमतियां लागू कर सकूं, और कुछ एपीआई अनुरोधों को प्रतिबंधित कर सकूं)

  • id
  • email
  • username
  • password_hash:

    MySQL डेटाबेस मैं उपयोग करने के लिए उपयोगकर्ताओं (user कहा जाता है) कि निम्नलिखित आत्म व्याख्यात्मक स्तंभ के लिए एक मेज है

ऐसा लगता है कि प्रमाणीकरण के लिए डी-फैक्टो मानक एएसपी.Net पहचान है। मैंने आखिरी घंटे बिताया है कि मौजूदा डीबी-फर्स्ट एंटिटी फ्रेमवर्क सेटअप के साथ पहचान कैसे काम करें।

The entity type ApplicationUser is not part of the model for the current context.

मैं मैं में पहचान डाटा स्टोर करने की जरूरत है मान:

अगर मैं उपयोगकर्ता डेटा पुनः प्राप्त करने ApplicationUser (MySQL डेटाबेस से संस्थाओं)user उदाहरणों भंडारण उदाहरणों के निर्माण के लिए प्रयास करते हैं, मैं निम्नलिखित त्रुटि मिलती है मेरा MySQL डेटाबेस, लेकिन ऐसा करने के तरीके पर कोई संसाधन नहीं मिला। मैंने ApplicationUser कक्षा को पूरी तरह से हटाने की कोशिश की है और user इकाई वर्ग IdentityUser से प्राप्त किया है, लेकिन UserManager.CreateAsync पर कॉल करने के परिणामस्वरूप LINQ से Entities रूपांतरण त्रुटियां हुईं।

मैं एक मौजूदा user इकाई रखने वाले वेब एपीआई 2 एप्लिकेशन में प्रमाणीकरण कैसे स्थापित करूं?

उत्तर

19

आप कहते हैं:

I want to implement a login/registration system (so that I can implement roles and permissions in the future, and restrict certain API requests).

How do I setup authentication in a Web API 2 application, having an existing user entity?

यह निश्चित रूप से मतलब है कि आप क्या नहीं जरूरत ASP.NET पहचान। एएसपी.नेट पहचान सभी उपयोगकर्ताओं की सामग्री को संभालने के लिए एक तकनीक है। यह वास्तव में प्रमाणीकरण तंत्र "बना" नहीं करता है। एएसपी.नेट पहचान ओविन प्रमाणीकरण तंत्र का उपयोग करती है, जो एक और चीज है।

क्या आप देख रहे हैं , लेकिन "अपने मौजूदा उपयोगकर्ता की मेज के साथ ASP.NET पहचान का उपयोग कैसे करें"

Owin उपयोग करने के लिए "कैसे Owin प्रमाणीकरण अपने मौजूदा उपयोगकर्ता तालिका का उपयोग कर कॉन्फ़िगर करने के लिए" नहीं है प्रमाणीकरण के लिए निम्न चरणों का पालन करें:

संकुल स्थापित करें:

Owin 
Microsoft.AspNet.Cors 
Microsoft.AspNet.WebApi.Client 
Microsoft.AspNet.WebApi.Core 
Microsoft.AspNet.WebApi.Owin 
Microsoft.AspNet.WebApi.WebHost 
Microsoft.Owin 
Microsoft.Owin.Host.SystemWeb 
Microsoft.Owin.Security 
Microsoft.Owin.Security.OAuth 

रूट फ़ोल्डर के अंदर Startup.cs फ़ाइल बनाएँ (examp le): सही तरीके से कॉन्फ़िगर

[assembly: OwinStartup(typeof(YourProject.Startup))] 
namespace YourProject 
{ 
    public class Startup 
    { 
     public void Configuration(IAppBuilder app) 
     { 
      var config = new HttpConfiguration(); 
      //other configurations 

      ConfigureOAuth(app); 
      app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 
      app.UseWebApi(config); 
     } 

     public void ConfigureOAuth(IAppBuilder app) 
     { 
      var oAuthServerOptions = new OAuthAuthorizationServerOptions() 
      { 
       AllowInsecureHttp = true, 
       TokenEndpointPath = new PathString("/api/security/token"), 
       AccessTokenExpireTimeSpan = TimeSpan.FromHours(2), 
       Provider = new AuthorizationServerProvider() 
      }; 

      app.UseOAuthAuthorizationServer(oAuthServerOptions); 
      app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); 
     } 
    } 

    public class AuthorizationServerProvider : OAuthAuthorizationServerProvider 
    { 
     public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 
     { 
      context.Validated(); 
     } 

     public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
     { 
      context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); 

      try 
      { 
       //retrieve your user from database. ex: 
       var user = await userService.Authenticate(context.UserName, context.Password); 

       var identity = new ClaimsIdentity(context.Options.AuthenticationType); 

       identity.AddClaim(new Claim(ClaimTypes.Name, user.Name)); 
       identity.AddClaim(new Claim(ClaimTypes.Email, user.Email)); 

       //roles example 
       var rolesTechnicalNamesUser = new List<string>(); 

       if (user.Roles != null) 
       { 
        rolesTechnicalNamesUser = user.Roles.Select(x => x.TechnicalName).ToList(); 

        foreach (var role in user.Roles) 
         identity.AddClaim(new Claim(ClaimTypes.Role, role.TechnicalName)); 
       } 

       var principal = new GenericPrincipal(identity, rolesTechnicalNamesUser.ToArray()); 

       Thread.CurrentPrincipal = principal; 

       context.Validated(identity); 
      } 
      catch (Exception ex) 
      { 
       context.SetError("invalid_grant", "message"); 
      } 
     } 
    } 
} 

उपयोग कार्यों को अधिकृत करने के [Authorize] विशेषता:

सुनिश्चित करें कि [OwinStartup विधानसभा] बनाते हैं।

api/security/tokenGrantType, UserName, और Password को भालू टोकन प्राप्त करने के लिए कॉल करें। इस तरह:

"grant_type=password&username=" + username + "&password=" password; 

Bearer "YOURTOKENHERE" रूप HttpHeader Authorization भीतर टोकन भेजें। इस तरह:

headers: { 'Authorization': 'Bearer ' + token } 

उम्मीद है कि यह मदद करता है!

+0

धन्यवाद, यही वह है जिसे मैं ढूंढ रहा था। क्षमा करें अगर मेरा प्रश्न अस्पष्ट था, लेकिन मैं एएसपी.NET पहचान की "भूमिका" से उलझन में था। –

+0

आपका स्वागत है दोस्त। यदि आपको कार्यान्वयन पर कुछ परेशानी है, तो यहां टिप्पणी करने में संकोच न करें –

+1

अरे, क्या आप मुझे बता सकते हैं कि उपरोक्त कोड में उपयोगकर्ता सेवा ऑब्जेक्ट क्या होगा? बस एक कस्टम क्लास ऑब्जेक्ट जो मेरे डीबी संदर्भ से कनेक्ट होगा और मेरे कस्टम उपयोगकर्ता को डीबी से वापस कर देगा? उपयोगकर्ता को IUser या कुछ भी के बाद वारिस नहीं करना है? – Savail

7

अपने DB स्कीमा क्योंकि डिफ़ॉल्ट UserStore आप को लागू करना चाहिए अपने स्वयं के UserStore और UserPasswordStore कक्षाएं तो UserManager करने के लिए उन्हें इंजेक्षन साथ संगत नहीं हैं। इस सरल उदाहरण पर विचार करें:

सबसे पहले अपने कस्टम उपयोगकर्ता वर्ग लिखने और IUser इंटरफ़ेस को लागू:

class User:IUser<int> 
{ 
    public int ID {get;set;} 
    public string Username{get;set;} 
    public string Password_hash {get;set;} 
    // some other properties 
} 

अब इस तरह अपने कस्टम UserStore और IUserPasswordStore वर्ग लेखक:

public class MyUserStore : IUserStore<User>, IUserPasswordStore<User> 
{ 
    private readonly MyDbContext _context; 

    public MyUserStore(MyDbContext context) 
    { 
     _context=context; 
    } 

    public Task CreateAsync(AppUser user) 
    { 
     // implement your desired logic such as 
     // _context.Users.Add(user); 
    } 

    public Task DeleteAsync(AppUser user) 
    { 
     // implement your desired logic 
    } 

    public Task<AppUser> FindByIdAsync(string userId) 
    { 
     // implement your desired logic 
    } 

    public Task<AppUser> FindByNameAsync(string userName) 
    { 
     // implement your desired logic 
    } 

    public Task UpdateAsync(AppUser user) 
    { 
     // implement your desired logic 
    } 

    public void Dispose() 
    { 
     // implement your desired logic 
    } 

    // Following 3 methods are needed for IUserPasswordStore 
    public Task<string> GetPasswordHashAsync(AppUser user) 
    { 
     // something like this: 
     return Task.FromResult(user.Password_hash); 
    } 

    public Task<bool> HasPasswordAsync(AppUser user) 
    { 
     return Task.FromResult(user.Password_hash != null); 
    } 

    public Task SetPasswordHashAsync(AppUser user, string passwordHash) 
    { 
     user.Password_hash = passwordHash; 
     return Task.FromResult(0); 
    } 
} 

अब आप बहुत ही है उपयोगकर्ता स्टोर बस उपयोगकर्ता प्रबंधक को इंजेक्ट करता है:

public class ApplicationUserManager: UserManager<User, int> 
{ 
    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    { 
     var manager = new ApplicationUserManager(new MyUserStore(context.Get<MyDbContext>())); 
     // rest of code 
    } 
} 

कृपया ध्यान दें कि आपने DbContext से IdentityDbContext से सीधे अपने डीबी संदर्भ वर्ग को वारिस करना होगा क्योंकि आपने अपना उपयोगकर्ता स्टोर लागू किया है।

संबंधित मुद्दे