C mvc ავტორიზაცია რეგისტრაციის გარეშე. ავთენტიფიკაციისთვის HTTP შეტყობინებების დამმუშავებლების გამოყენება. უსაფრთხოების კონტექსტის დაყენება

  • სახელმძღვანელო

გაკვეთილის მიზანი: Cookie-ის მეშვეობით ავტორიზაციის მეთოდის შესწავლა, კონტროლერისა და კონტროლერის მეთოდის სტანდარტული წვდომის ატრიბუტების გამოყენება. IPrincipal-ის გამოყენება. საკუთარი მოდულის (IHttpModule) და საკუთარი IActionFilter-ის შექმნა.

მცირე გადახვევა: სინამდვილეში, asp.net mvc-ში, ყველა სახელმძღვანელო გირჩევთ გამოიყენოთ უკვე გამოგონილი ავტორიზაციის სისტემა, სახელწოდებით AspNetMembershipProvider, ეს აღწერილი იყო სტატიაში http://habrahabr.ru/post/142711/ (წვდომა ახლა დახურულია), მაგრამ განმარტა, რომ ეს არის "დაეხვიე და არ მესმის, რა არის შიგნით." როდესაც პირველად გავიცანი asp.net mvc, ამან დამაბნია. გარდა ამისა, ამ სტატიაში http://habrahabr.ru/post/143024/ ნათქვამია, რომ თქვენ არ შეგიძლიათ გამოიყენოთ ეს პროვაიდერი. და მე ვეთანხმები ამას. აქ ჩვენ საკმაოდ ღრმად ვსწავლობთ ყველა სახის სახიფათო asp.net mvc-ს სტანდარტული ტექნიკაასე რომ, ეს არის ერთ-ერთი მთავარი გაკვეთილი.

Cookies Cookies არის სერვერის მიერ ბრაუზერში გაგზავნილი ინფორმაციის ნაწილი, რომელსაც ბრაუზერი უბრუნებს სერვერს თითოეულ (თითქმის ყველა) მოთხოვნასთან ერთად.

სერვერი პასუხების სათაურში წერს:
Set-Cookie: value[; ვადის გასვლის=თარიღი][; დომენი=დომენი][; გზა=გზა][; უსაფრთხო]
მაგალითად:

HTTP/1.1 200 OK Content-type: text/html Set-Cookie: name=value Set-Cookie: name2=value2; იწურება = ოთხშაბათი, 09-ივნ-2021 10:18:14 GMT
ბრაუზერი (თუ ქუქი-ფაილის ვადა არ გასულა) თითოეულ მოთხოვნაზე:
GET /spec.html HTTP/1.1 ჰოსტი: www.example.org ქუქი: name=value; name2=value2 მიღება: */*

დააყენეთ ქუქი (/Areas/Default/Controllers/HomeController.cs):
public ActionResult Index() ( var cookie = new HttpCookie() ( Name = "test_cookie", Value = DateTime.Now.ToString("dd.MM.yyyy"), Expires = DateTime.Now.AddMinutes(10), ); Response.SetCookie(cookie return View();

Chrome-ში ჩვენ ვამოწმებთ ინსტალაციას:

ქუქიების მისაღებად:
var cookie = Request.Cookies["test_cookie"];

მოდით გავაკეთოთ წყვეტის წერტილი და შევამოწმოთ:

შენიშვნა: შეგიძლიათ მეტი გაიგოთ ქუქიების შესახებ შემდეგ ბმულზე:
http://www.nczonline.net/blog/2009/05/05/http-cookies-explained/

ავტორიზაცია ჩვენს შემთხვევაში, ავტორიზაცია დაფუძნებული იქნება ქუქიების გამოყენებაზე. ამისათვის შევისწავლოთ შემდეგი დებულებები:
  • FormsAuthenticationTicket - ამ კლასს გამოვიყენებთ ავტორიზაციის მონაცემების დაშიფრული ფორმით შესანახად
  • თქვენ უნდა განახორციელოთ IPrincipal ინტერფეისი და დააყენოთ HttpContext.User როლების და IIdentity ინტერფეისის შესამოწმებლად.
  • გააკეთეთ განხორციელება IIdentity ინტერფეისისთვის
  • BaseController თვისებაში გამოიტანეთ CurrentUser იმ მომხმარებლის მნიშვნელობა, რომელიც ამჟამად შესულია.

მოდი დავიწყოთ.
მოდით შევქმნათ IAuthentication ინტერფეისი და მისი განხორციელება CustomAuthentication (/Global/Auth/IAuthentication.cs):

საჯარო ინტერფეისი IA ავთენტიფიკაცია ( /// /// კონტექსტი (აქ ვიღებთ წვდომას მოთხოვნასა და ქუქი-ფაილებზე) /// HttpContext HttpContext ( მიიღეთ; დაყენება; ) მომხმარებლის შესვლა (სტრიქონის შესვლა, სტრიქონის პაროლი, bool isPersistent); მომხმარებლის შესვლა (სტრიქონი შესვლა void LogOut(Principal CurrentUser)

იმპლემენტაცია (/Global/Auth/CustomAuthentication.cs):
საჯარო კლასი CustomAuthentication: IAuthentication ( private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); private const string cookieName = "__AUTH_COOKIE"; საჯარო HttpContext HttpContext ( get; set; ) public IReposit IAuthentication წევრების საჯარო მომხმარებლის შესვლა (სტრიქონი მომხმარებლის სახელი, სტრიქონი პაროლი, bool isPersistent) ( მომხმარებლის retUser = Repository.Login (userName, Password); if (retUser != null) ( CreateCookie (userName, is Persistent); ) დააბრუნეთ retUser; შესვლა (სტრიქონის მომხმარებლის სახელი) ( მომხმარებლის retUser = Repository.Users.FirstOrDefault(p => string.Compare(p.ელფოსტა, მომხმარებლის სახელი, true) == 0); if (retUser != null) ( CreateCookie(userName); ) დაბრუნება retUser ) private void CreateCookie(string userName, bool isPersistent = false) ( var ბილეთი = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.Add(FormsAuthentication.Timeout), isPersistent.Authentication.Timeout, st. ); // ბილეთის დაშიფვრა.ფუნთუშა.

var AuthCookie = new HttpCookie(cookieName) ( Value = encTicket, Expires = DateTime.Now.Add(FormsAuthentication.Timeout) );

HttpContext.Response.Cookies.Set(AuthCookie);

) საჯარო void LogOut() ( var httpCookie = HttpContext.Response.Cookies; if (httpCookie != null) ( httpCookie.Value = string.Empty; ) ) private IPrincipal _currentUser; საჯარო IP Principal CurrentUser ( მიიღეთ ( if (_currentUser == null) ( სცადეთ ( HttpCookie authCookie = HttpContext.Request.Cookies.Get(cookieName); if (authCookie != null && !string.IsNullOrEmpty) (Vuealth) = FormsAuthentication.Decrypt(authCookie.Value) _currentUser = new UserProvider(ticket.Name, Repository else ( _currentUser = new UserProvider(null, null); ) catch (Exception ex) (logger.Error:"Failed authentication); " + ex.Message); _currentUser = new UserProvider(null, null); ) ) return _currentUser; ) ) #endregion )დასკვნა ასეთია: მოთხოვნის ინიციალიზაციისას ჩვენ შევდივართ HttpContext.Request.Cookies და ვაწყდებით UserProvider-ს:
Var ბილეთი = FormsAuthentication.Decrypt(authCookie.Value); _currentUser = new UserProvider(ticket.Name, Repository);

დამატებულია ავტორიზაციისთვის IRepository-ში
ახალი მეთოდი

IRepository. შესვლა. დანერგვა SqlRepository-ში:

საჯარო მომხმარებლის შესვლა (სტრიქონი ელფოსტა, სტრიქონი პაროლი) ( დაბრუნება Db.Users.FirstOrDefault(p => string.Compare(p.ელ.ფოსტა, ელფოსტა, true) == 0 && p. პაროლი == პაროლი); )

საჯარო bool InRoles(string როლები) ( if (string.IsNullOrWhiteSpace(roles)) ( return false; ) var rolesArray = roles.Split(new ( "," ), StringSplitOptions.RemoveEmptyEntries); foreach (var როლი rolesArray-ში) ( var hasRole = UserRoles.Any(p => string.Compare(p.Role.Code, role, true) == 0 if (hasRole) ( return true; ) return false)

InRoles მეთოდში, ჩვენ ველით მოთხოვნას იმ როლების შესახებ, რომლებიც დაშვებულია რესურსზე, გამოყოფილი მძიმით. ეს არის, მაგალითად, "ადმინისტრატორი, მოდერატორი, რედაქტორი", თუ ჩვენს მომხმარებელს აქვს მინიმუმ ერთი როლი, მაშინ ჩვენ ვაბრუნებთ მნიშვნელობას "true" (არსებობს წვდომა). ჩვენ ვადარებთ Role.Code ველს და არა Role.Name-ს.
განვიხილოთ UserIdentity კლასი (/Global/Auth/UserIdentity.cs):
საჯარო კლასი UserIndentity: IIdentity (public User User ( get; set; ) public string AuthenticationType (get ( return typeof(User).ToString(); ) public bool IsAuthenticated (get ( return User != null; ) ) public string სახელი ( get ( if (User != null) ( return User.Email; ) //სხვა ანონიმური დაბრუნება "anonym"; ) ) public void Init(string email, IRepository repository) ( if (!string.IsNullOrEmpty(email)) ( მომხმარებელი = repository.GetUser(email);
ჩვენ ვამატებთ ახალ მეთოდს GetUser(email) IRepository-ში. დანერგვა SqlRepository.GetUser()-ისთვის (LessonProject.Model:/SqlRepository/User.cs):

საჯარო მომხმარებელი GetUser(სტრიქონი ელფოსტა) ( დაბრუნება Db.Users.FirstOrDefault(p => string.Compare(p.ელ.ფოსტა, ელფოსტა, true) == 0); )

თითქმის ყველაფერი მზადაა. მოდით ვაჩვენოთ CurrentUser BaseController-ში:
საჯარო IAuthentication Auth ( მიღება; კომპლექტი; ) საჯარო მომხმარებელი CurrentUser ( მიღება ( დაბრუნება ((UserIndentity)Auth.CurrentUser.Identity). მომხმარებელი; ) )

დიახ, ეს არ არის ძალიან სწორი, რადგან არსებობს ძლიერი სავალდებულო. მაშასადამე, მოდით გავაკეთოთ ეს, წარმოგიდგინოთ სხვა ინტერფეისი IUserProvider, საიდანაც მოვითხოვთ ავტორიზებული მომხმარებლის დაბრუნებას:
საჯარო ინტერფეისი IUserProvider ( მომხმარებლის მომხმარებელი ( მიიღეთ; კომპლექტი; ) ) ... საჯარო კლასი UserIndentity: IIdentity, IUserProvider ( /// /// მიმდინარე მომხმარებელი /// საჯარო მომხმარებლის მომხმარებელი ( მიიღეთ; კომპლექტი; ) ... საჯარო IA ავთენტიფიკაციის ავტორიზაცია ( მიიღეთ; დაყენება ; ) საჯარო მომხმარებელი CurrentUser ( მიიღეთ ( დაბრუნება ((IUserProvider)Auth.CurrentUser.Identity). მომხმარებელი; ) )
ახლა ვცადოთ ყველაფრის ინიციალიზაცია.
პირველ რიგში, მოდით დავამატოთ ჩვენი IAuthentication + CustomAuthentication Ninject რეგისტრაციას (/App_Start/NinjectWebCommon.cs):

Kernel.Bind().To().InRequestScope();

შემდეგ ჩვენ შევქმნით მოდულს, რომელიც შეასრულებს ავტორიზაციის მოქმედებას AuthenticateRequest ღონისძიებაზე:
საჯარო კლასი AuthHttpModule: IHttpModule ( public void Init(HttpApplication context) (context.AuthenticateRequest += new EventHandler(this.Authenticate); ) private void Authenticate(Object source, EventArgs e) (HttpApplicationppttAppontexsource) app.Context var auth = DependencyResolver.Current.GetService();

ყველა მარილი არის ხაზებში: auth.HttpContext = კონტექსტი და კონტექსტი. მომხმარებელი = auth.CurrentUser . როგორც კი ჩვენი ავტორიზაციის მოდული გაიგებს კონტექსტს და მასში შემავალ ქუქი-ფაილებს, ის მაშინვე იღებს წვდომას სახელზე, მისი გამოყენებით იღებს მომხმარებლის მონაცემებს საცავში და აბრუნებს მას BaseController-ში. მაგრამ არა ყველაფერი ერთდროულად, არამედ მოთხოვნით.
ჩვენ ვუკავშირდებით მოდულს Web.config-ში:

გეგმა არის:

  • ზედა ნაწილში ჩვენ ვაჩვენებთ არის თუ არა მომხმარებელი ავტორიზებული თუ არა. თუ ავტორიზებულია, მაშინ მისი ელფოსტა და ბმული გამოსვლისთვის, თუ არა, მაშინ ბმულები შესვლისა და რეგისტრაციისთვის
  • შესვლის ფორმის შექმნა
  • თუ მომხმარებელმა სწორად შეიყვანა მონაცემები, ვაძლევთ უფლებას და ვაგზავნით მთავარ გვერდზე
  • თუ მომხმარებელი გამოდის, მაშინ ჩვენ ვკლავთ მის ავტორიზაციას

მოდით წავიდეთ. დაამატეთ Html.Action(“UserLogin”, “Home”) – ეს არის ნაწილობრივი ხედი (ანუ კოდის ნაწილი, რომელსაც არ აქვს განლაგება) – ე.ი. ნაჩვენებია იქ, სადაც ის რეგისტრირებულია და არა RenderBody().
_Layout.cshtml (/Areas/Default/Views/Shared/_Layout.cshtml):

@RenderBody() HomeController.cs: საჯარო ActionResult UserLogin() ( დაბრუნება View(CurrentUser); )

UserLogin.cshtml (/Areas/Default/Views/Home/UserLogin.cshtml):

@model LessonProject.Model.User @if (Model != null) (

  • @Model.Email
  • @Html.ActionLink ("გასვლა", "გამოსვლა", "შესვლა")
  • ) სხვა (
  • @Html.ActionLink ("შესვლა", "ინდექსი", "შესვლა")
  • @Html.ActionLink ("რეგისტრაცია", "რეგისტრაცია", "მომხმარებელი")
  • }

    LoginController შესვლა/გამომავალი კონტროლერი (/Areas/Default/Controllers/LoginController.cs):

    საჯარო კლასის LoginController: DefaultController ( public ActionResult Index() ( return View(new LoginView()); ) public ActionResult Index(LoginView loginView) ( if (ModelState.IsValid) ( var user = Auth.Login(loginView.Email,. პაროლი, loginView.IsPersistent if (user != null) ( return RedirectToAction("Index", "Home"); ) ModelState["Password"].Errors.Add("პაროლი არ ემთხვევა" ) return View(loginView); ) public ActionResult Logout() (Auth.LogOut(); return RedirectToAction("Index", "Home"); ) )

    LoginView.cs (/Models/ViewModels/LoginView.cs):
    საჯარო კლასი LoginView ( საჯარო სტრიქონი ელფოსტა ( მიიღეთ; დაყენება; ) საჯარო სტრიქონი პაროლი ( მიიღეთ; დაყენება; ) საჯარო bool IsPersistent (მიღება; დაყენება; ))

    შესვლის გვერდი Index.cshtml (/Areas/Default/Views/Index.cshtml):

    @model LessonProject.Models.ViewModels.LoginView @( ViewBag.Title = " შესვლა"; Layout = "~/Areas/Default/Views/Shared/_Layout.cshtml"; } Вход @using (Html.BeginForm("Index", "Login", FormMethod.Post, new { @class = "form-horizontal" })) { Вход Email @Html.TextBox("Email", Model.Email, new { @class = "input-xlarge" }) !}

    შეიყვანეთ ელფოსტა

    @Html.ValidationMessage("ელფოსტა") პაროლი @Html.Password("პაროლი", Model.Password, ახალი ( @class = "input-xlarge" )) @Html.ValidationMessage("პაროლი") შესვლა )

    მოდით გავიქცეთ და შევამოწმოთ:

    ყველა წყარო მდებარეობს

    სერგეი ბაკლანოვი

    Imports System.Data.SqlClient Imports System.Web.Security საჯარო კლასის შესვლა მემკვიდრეობით System.Web.UI.Page Protected WithEvents txtName As System.Web.UI.WebControls.TextBox Protected WithEvents txtPassword As System.WebControlTUI. WithEvents lbl As System.Web.UI.WebControls.Label Protected WithEvents btnLogin As System.Web.UI.WebControls.Button #Region " Web Form Designer Genered Code " "ეს ზარი საჭიროა ვებ ფორმის დიზაინერის მიერ. Private Sub InitializeComponent() ბოლო ქვე "შენიშვნა: შემდეგიადგილის მფლობელის დეკლარაცია საჭიროა ვებ ფორმის დიზაინერის მიერ. "არ წაშალოთ და არ გადაიტანოთ იგი. პირადი დიზაინერიPlaceholderDeclaration As System.Object Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init "CODEGEN: ეს მეთოდის გამოძახება საჭიროა ვებ ფორმის დიზაინერის მიერ " არ შეცვალოთ ის კოდის რედაქტორის გამოყენებით InitializeComponent() End Sub #End Region Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) ამუშავებს MyBase.Load "დააყენე მომხმარებლის კოდი გვერდის ინიციალიზაციისთვის. Private Sub btnLogin_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnLogin.Click Dim cn As New SqlConnection("server=localhost;database=FormAuthUsers;uid=sa;pwd=cmdman;Sqlm") "FindUser", cn) Dim dr როგორც SqlDataReader Dim ბილეთი როგორც FormsAuthenticationTicket Dim n როგორც მთელი რიცხვი, strRoles როგორც სტრიქონი, strEncrypted როგორც სტრიქონი. დაასრულეთ სცადეთ " დააყენეთ ბრძანების ტიპი cm.CommandType = CommandType.StoredProcedure " სახელის პარამეტრების დამატება Dim prmName = New SqlParameter("@Name", SqlDbType.NVarChar, 50) prmName.Value = txtName.Para.Name.Ts " პაროლის პარამეტრის დამატება Dim prmPass = New SqlParameter("@Password", SqlDbType.NVarChar, 50) prmPass.Value = txtPassword.Text cm.Parameters.Add(prmPass) " შეასრულეთ მოთხოვნა n =Cal>Scal.If.Exe. " თუ მომხმარებელი არსებობს იგივე სახელით და პაროლით, მაშინ ჩვენ ვეძებთ მის როლებს cm = Nothing cm = New SqlCommand("exec FindRoles "" & txtName.Text & """, cn) dr = cm.ExecuteReader() " როლების სიის შედგენა dr.Read If strRoles = "" შემდეგ strRoles &= dr(0) Else strRoles &= ", " & dr(0) End If End სანამ " შექმენით ავტორიზაციის ბილეთი = New FormsAuthenticationTicket(1, txtName.Text, DateTime.Now, _ DateTime .Now.AddMinutes(20), False, strRoles) " ბილეთის დაშიფვრა strEncrypted = FormsAuthentication.Encrypt(ბილეთი) " Save the cookie Response.Cookies.Add(New Httpl" , strEncrypted)) " დაბრუნებამთავარი გვერდი

    ამ მაგალითში ჩვენ განვათავსეთ ორი გადამოწმების ოპერაცია ერთ პროცედურაში: ერთი ავთენტიფიკაციისთვის, მეორე ავტორიზაციისთვის. პირველ რიგში, ჩვენ ვამოწმებთ ავთენტიფიკაციას მონაცემთა ბაზიდან ამა თუ იმ სახელისა და პაროლის მქონე მომხმარებლისთვის მონაცემების მოთხოვნით. თუ მომხმარებელი ვერ მოიძებნა, ჩვენ ვაჩვენებთ შესაბამის შეცდომის შეტყობინებას (იხ. სტრიქონი 4 ქვემოთ). თუ მომხმარებელი აღმოჩენილია, მაშინ ჩვენ განვსაზღვრავთ მის როლებს მონაცემთა ბაზიდან ინფორმაციის ხელახლა მოთხოვნით. მიღებული როლური ინფორმაციის საფუძველზე, გენერირდება ავტორიზაციის ბილეთი, რომელიც შემდგომში დაშიფრულია და ინახება ქუქიში. და ბოლოს, მომხმარებელი უსაფრთხოდ უბრუნდება default.aspx გვერდზე.

    ვინაიდან ჩვენმა კონფიგურაციის ფაილმა განსაზღვრა წვდომის შეზღუდვები რამდენიმე ფაილზე, მოდით გადავხედოთ მათ შინაარსს (ჩამონათვალი 7).

    ჩამონათვალი 7. default.aspx

    AuthzByUrl Sub Page_Load(გამომგზავნი როგორც ობიექტი, e როგორც EventArgs) ამუშავებს MyBase.Load If HttpContext.Current.User.Identity.Name = "" შემდეგ lblLogin.Text = "თქვენ არ ხართ დარეგისტრირებული, გთხოვთ შეხვიდეთ" Else lblLogin.Text თქვენ დარეგისტრირებული ხართ როგორც " & _ HttpContext.Current.User.Identity.Name End If End Sub Sub btnLogin_Click(გამომგზავნი როგორც ობიექტი, e როგორც EventArgs) ამუშავებს btnLogin.Click Response.Redirect("login.aspx") დასრულება Sub You" არ ხარ დარეგისტრირებული, გთხოვთ შეხვიდეთ
    გადასვლა:
    • ადმინისტრაციული ზონა
    • მომხმარებლის ზონა

    admin.aspx

    ადმინისტრატორი

    მას შემდეგ რაც შექმნით ამ მარტივ ვებსაიტს, თქვენ შეძლებთ საკუთარი თვალით ნახოთ თქვენი შრომის ნაყოფი. ზემოაღნიშნული კოდი შეიცავს ყველა ინსტრუქციას, რომელიც აუცილებელია საიტისთვის ფუნქციონალური უსაფრთხოების სისტემის შესაქმნელად, ფორმის ავთენტიფიკაციისა და URL ავტორიზაციის საფუძველზე.

    სესხის აღების უფლებამოსილება

    პრივილეგიური სესხება არის ოპერაციული რეჟიმი, რომელშიც ASP.NET აპლიკაცია გადის სახელით. კონკრეტული მომხმარებელი. როგორც ჩანს, რა აზრი აქვს სესხის აღების უფლებამოსილებას, თუ ვინდოუსის ავტორიზაციის დროს მომხმარებელი უკვე შედის კონკრეტული ანგარიშით? მაგრამ მთელი საქმე იმაში მდგომარეობს, რომ მომხმარებლის ID ავტორიზაციისთვის და მომხმარებლის ID სესხის აღების უფლებამოსილებისთვის არის სხვადასხვა რამ და ისინი შესაბამისად გამოიყენება სხვადასხვა ინფორმაციის მისაღებად.

    ნაგულისხმევად, ASP.NET-ში სესხის აღების რეჟიმი გამორთულია. მის გასააქტიურებლად, თქვენ უნდა დაამატოთ ტეგი Web.config ფაილში და დააყენოთ მისი იმიტირებული ატრიბუტი true. პროექტის კონფიგურაციის ფაილიდან შემდეგი ფრაგმენტი გვიჩვენებს, როგორი უნდა იყოს ეს:

    Web.config

    იმის საჩვენებლად, თუ როგორ მუშაობს ეს რეჟიმი, გამოიყენეთ შემდეგი კოდი(ჩამონათვალი 8) default.aspx გვერდზე:

    ნაგულისხმევი.aspx

    იმიტაცია მომხმარებელი:ავთენტიფიცირებულია ავთენტიფიკაციის ტიპი სახელი WindowsIdentity:ავთენტიფიცირებულია ავთენტიფიკაციის ტიპი სახელი

    default.aspx.vb

    Imports System.Security.Principal Public Class WebForm1 მემკვიდრეობით System.Web.UI.Page #Region "Web Form Designer Generated Code" "ეს ზარი საჭიროა ვებ ფორმის დიზაინერის მიერ. Private Sub InitializeComponent() End Sub "შენიშვნა: შემდეგი ჩანაცვლების ადგილი დეკლარაცია საჭიროა ვებ ფორმის დიზაინერის მიერ.

    "არ წაშალოთ და არ გადაიტანოთ იგი. პირადი დიზაინერიPlaceholderDeclaration As System.Object Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init "CODEGEN: ეს მეთოდის გამოძახება საჭიროა ვებ ფორმის დიზაინერის მიერ " არ შეცვალოთ ის კოდის რედაქტორის გამოყენებით InitializeComponent() End Sub #End Region Protected WithEvents clmIsAuthU As System.Web.UI.HtmlControls.HtmlTableCell Protected WithEvents clmAuthTypeU As System.Web.UI.HtmlUAssystemControlables. .Ui.htmlcontrols.htmltablecell დაიცვეს ClMisauthw, როგორც system.web.ui.htmlcontrols.htmltablecell დაიცვა clmauthtypew as system.web.web.ui.htmlcontrols.htmltablecelts. ecell private sub page_load (byval გამგზავნი As System.Object, ByVal e As System.EventArgs) ამუშავებს MyBase.Load Dim wi As WindowsIdentity " User.Identity With context.User.Identity clmIsAuthU.InnerText = .IsAuthenticated.ToString clmAuthTypeUTextication.Ainner nerText = .Name End With "System.Security.Principal.WindowsIdentity wi = WindowsIdentity.GetCurrent With wi clmIsAuthW.InnerText = .IsAuthenticated.ToString clmAuthTypeW.InnerText = .Nauthentication ქვედა კლასი

    ფორმის load event handler-ში WindowsIdentity ობიექტის მომხმარებლის იდენტიფიკატორის მისაღებად გამოიყენება GetCurrent მეთოდი, რომელიც აბრუნებს იმ ანგარიშის იდენტიფიკატორს, რომლის მიხედვითაც მუშაობს ASP.NET პროცესი.

    როდესაც ამ აპლიკაციის გაშვებას ნებართვის სესხება () გამორთულია, დაინახავთ 3-ზე გამოსახულ ეკრანს. როგორც ხედავთ, როდესაც ნებართვის სესხება გამორთულია, WindowsIdentity ობიექტი შეიცავს ASPNET სისტემის მომხმარებლის ID-ს.

    ახლა, თუ ჩართავთ სესხის აღებას, ნახავთ შედეგს, რომელიც ნაჩვენებია ცხრილში 1.

    WindowsIdentity:

    ცხრილი 1. პრივილეგიის სესხება ჩართულია და ანონიმური წვდომა გამორთულია ავთენტიფიცირებულია
    მართალია მოლაპარაკება
    სახელი BIGDRAGON\B@k$
    ცხრილი 1. პრივილეგიის სესხება ჩართულია და ანონიმური წვდომა გამორთულია ავთენტიფიცირებულია
    მართალია NTLM
    სახელი BIGDRAGON\B@k$

    როგორც ხედავთ, შედეგები იგივეა, რადგან ორივე ობიექტი იღებს ინფორმაციას მიმდინარე მომხმარებლის შესახებ. მაგრამ წინა ორი მაგალითი ფოკუსირებული იყო პირობებზე ავტორიზაციისთვის აკრძალული ანონიმური წვდომით Windows-ის გამოყენებით. თუ აპლიკაციაზე ანონიმურ წვდომას დაუშვებთ, User.Identity ობიექტი არ დააბრუნებს მომხმარებლის სახელს და მისი IsAuthenticated თვისება იქნება False. ეს გასაკვირი არ არის, რადგან თუ ანონიმური წვდომა ნებადართულია Windows ავტორიზაციის სისტემაში, მაშინ მომხმარებელი მუშაობს ანონიმურად, ანუ არ გადის ავტორიზაციას.

    ამავდროულად, WindowsIdentity ობიექტს ექნება IsAuthenticated თვისება ღირებულება Trueდა მომხმარებლის სახელი იქნება შემდეგი ფორმატის სტრიქონი: IUSR_, როგორც ნაჩვენებია ცხრილში 2.

    ცხრილი 2. დასაშვებია სესხის აღების ნებართვები და ანონიმური წვდომა

    WindowsIdentity:

    ცხრილი 1. პრივილეგიის სესხება ჩართულია და ანონიმური წვდომა გამორთულია ყალბი
    მართალია
    სახელი
    ცხრილი 1. პრივილეგიის სესხება ჩართულია და ანონიმური წვდომა გამორთულია ავთენტიფიცირებულია
    მართალია NTLM
    სახელი BIGDRAGON\IUSR_BIGDRAGON

    WindowsIdentity ობიექტის სახელის თვისებას აქვს ეს მნიშვნელობა, რადგან ის აბრუნებს მომხმარებლის ID-ს, რომლის მიხედვითაც მიმდინარეობს ASP.NET პროცესი და არა ვებსაიტის მომხმარებელი. და რადგანაც პროცესი ანონიმურად ვერ აწარმოებს, ის იღებს სახელს IIS-დან, თუ მისი მიღება შეუძლებელია მიმდინარე მომხმარებლისგან.

    თუ ფრთხილად იყავით ოპერაციების შესრულებისას ანონიმური წვდომის დაშვების/უარყოფის მიზნით, შესაძლოა შეამჩნევდით, რომ მომხმარებლის სახელი ველში იყო ჩასმული ზემოთ მოცემული ფორმატის სტრიქონი: IUSR_ (ნახ. 4).

    სურათი 4. მომხმარებლის სახელის ველი შეიცავს სტრიქონს, რომელიც განსაზღვრავს ASP.NET პროცესის სახელს ანონიმურად წვდომისას.

    გარდა ამისა, ASP.NET იძლევა შესაძლებლობას მიუთითოთ ვისგან უნდა აიღოთ ნებართვები. ამ მიზნით, ტეგი უზრუნველყოფს userName ატრიბუტს, რომელიც მიუთითებს მომხმარებლის სახელზე, ვისგანაც აუცილებელია ნებართვების სესხება.

    შემდეგი ფრაგმენტი Web.config ფაილიდან გვიჩვენებს, როგორი უნდა იყოს ეს პრაქტიკაში:

    Web.config:

    სატესტო აპლიკაციის ამ კონფიგურაციით შესასრულებლად გაშვების შემდეგ, User.Identity ობიექტის მდგომარეობა დარჩება უცვლელი, მაგრამ WindowsIdentity ობიექტის სახელის თვისებაში, IUSR_ ფორმატის სტრიქონის ნაცვლად, ტეგის userName ატრიბუტში მითითებული სახელი. პროექტის კონფიგურაციის ფაილიდან გამოჩნდება, როგორც ეს ნაჩვენებია ცხრილში 3.

    ცხრილი 3. ASP.NET პროცესი მიმდინარეობს როგორც კონკრეტული მომხმარებელი

    WindowsIdentity:

    ცხრილი 1. პრივილეგიის სესხება ჩართულია და ანონიმური წვდომა გამორთულია ყალბი
    მართალია
    სახელი
    ცხრილი 1. პრივილეგიის სესხება ჩართულია და ანონიმური წვდომა გამორთულია ავთენტიფიცირებულია
    მართალია NTLM
    სახელი BIGDRAGON\AlBa

    თუ გააუქმებთ ანონიმურ წვდომას, User.Identity ობიექტი შეიცავს შესული მომხმარებლის ID-ს, მაგრამ WindowsIdentity ობიექტი კვლავ შეიცავს მომხმარებლის სახელს userName ატრიბუტით.

    ამით დასრულდა ჩვენი შესწავლა ავტორიზაციის, როგორც უსაფრთხოების საშუალების შესახებ ASP.NET გარემოში. ავტორიზაციის მექანიზმის შემდგომი შესწავლა საშუალების შესწავლას მოითხოვს Windows ავტორიზაცია. მათ შორის არის წვდომის კონტროლის სიები დაბალი და მაღალი დონის, კლიენტის/სერვერის არქიტექტურის წვდომის კონტროლი, Windows როლებზე დაფუძნებული უსაფრთხოება და ა.შ.

    თუ ეს თემა ნამდვილად გაინტერესებთ, მაშინ შეგიძლიათ იპოვოთ ბევრი მასალა MSDN ბიბლიოთეკაში:

    • უსაფრთხოების თემები ASP.NET-ში ხელმისაწვდომია MSDN ბიბლიოთეკის შემდეგ ფილიალში: .NET Development/.NET Security;
    • მთლიანი სისტემის უსაფრთხოებასთან დაკავშირებული კითხვებისთვის, გთხოვთ, ეწვიოთ უსაფრთხოების/უსაფრთხოების (ზოგადი)/SDK დოკუმენტაციის განყოფილებას.

    თუ არ გაქვთ MSDN ბიბლიოთეკა, მაშინ მის უახლეს გამოცემაზე წვდომა შესაძლებელია ინტერნეტის საშუალებით: http://msdn.microsoft.com/library/.

    ამ სტატიის მესამე და ბოლო ნაწილში განვიხილავთ ძალიან აქტუალურ და საინტერესო თემა- კრიპტოგრაფია. კრიპტოგრაფიის თეორიისა და ალგორითმების გარდა, სხვადასხვა კუთხით შევხედავთ .NET Framework-ის მიერ მოწოდებულ დაშიფვრის ინსტრუმენტებს და შევქმნით დაშიფვრის მარტივ მეთოდს.

    ჯერჯერობით, ჩვენ მხოლოდ ვაჩვენეთ, თუ როგორ უნდა გადავამოწმოთ, რომ მომხმარებლები არიან ისინი, ვინც ამბობენ, რომ არიან და როგორ ამოიღონ ინფორმაცია ავთენტიფიცირებული პირადობის შესახებ. ეს აპებს აძლევს მომხმარებლებს შორის დიფერენცირების ძირითად უნარს, მაგრამ ეს მხოლოდ საწყისი წერტილია. მართლაც უსაფრთხო ვებ აპლიკაციის შესაქმნელად, თქვენ დაგჭირდებათ მათი ავთენტიფიკაცია აპლიკაციის სხვადასხვა ადგილას.

    ავტორიზაცია არის პროცესი, რომელიც განსაზღვრავს, აქვს თუ არა ავთენტიფიცირებულ მომხმარებელს საკმარისი პრივილეგიები კონკრეტული მოქმედების შესასრულებლად. ეს ქმედება შეიძლება იყოს ვებ გვერდის მოთხოვნა, ოპერაციული სისტემის მიერ მართულ რესურსზე წვდომა (როგორიცაა ფაილი ან მონაცემთა ბაზა), ან აპლიკაციისთვის სპეციფიკური ამოცანების შესრულება (როგორიცაა შეკვეთის განთავსება შეკვეთის მართვის სისტემაში ან პროექტის მინიჭება პროექტის მენეჯმენტში. განაცხადის მსგავსი Microsoft Projectსერვერი).

    ამ შემოწმებებიდან ზოგიერთი Windows-ის მიერ ავტომატურად ხორციელდება, ზოგი კი დეკლარაციულად შეიძლება იყოს კოდირებული web.config ფაილის გამოყენებით. მაგრამ ზოგიერთი შემოწმება უნდა განხორციელდეს პირდაპირ კოდით IPrincipal ობიექტის გამოყენებით.

    URL ავტორიზაცია

    ნებართვების დაყენების უმარტივესი გზაა მათი დაყენება ცალკეულ ვებ გვერდებზე, ვებ სერვისებსა და ქვედირექტორიებზე. იდეალურ შემთხვევაში, ვებ აპლიკაციის პლატფორმამ უნდა უზრუნველყოს რესურსის სპეციფიკური ავტორიზაცია კოდის შეცვლის ან აპლიკაციის ხელახლა შედგენის გარეშე. ASP.NET მხარს უჭერს ამ მოთხოვნას დეკლარაციული ავტორიზაციის წესების მეშვეობით, რომლებიც შეიძლება განისაზღვროს web.config ფაილში.

    თქვენ მიერ განსაზღვრული წესები მოქმედებს სპეციალური HTTP მოდულის მეშვეობით, სახელწოდებით UrlAuthorizationModule. მოდული უყურებს ამ წესებს და ამოწმებს თითოეულ მოთხოვნას, დარწმუნდება, რომ მომხმარებელს არ აქვს წვდომა სპეციალურად შეზღუდულ რესურსებზე.

    ამ ტიპის ავტორიზაციას URL ავტორიზაცია ეწოდება, რადგან ის ითვალისწინებს მხოლოდ ორ დეტალს - მომხმარებლის უსაფრთხოების კონტექსტს და იმ რესურსის URL-ს, რომლის წვდომას მომხმარებელი ცდილობს. თუ გვერდზე წვდომა უარყოფილია და გამოყენებული იქნება ფორმების ავთენტიფიკაცია, მომხმარებელი გადამისამართდება რეგისტრაციის გვერდზე.

    ავტორიზაციის წესები

    სხვა სიტყვებით რომ ვთქვათ, არსებობს ორი სახის წესი: დაშვება და უარყოფა. შეგიძლიათ დაამატოთ რამდენიც გსურთ. თითოეული წესი განსაზღვრავს ერთ ან მეტ მომხმარებელს ან როლს (მომხმარებელთა ჯგუფებს). გარდა ამისა, შეგიძლიათ გამოიყენოთ ზმნის ატრიბუტი, რათა შექმნათ წესები, რომლებიც ვრცელდება მხოლოდ კონკრეტული ტიპის HTTP მოთხოვნებისთვის (GET, POST, HEAD OR DEBUG).

    უკვე ნახსენები წინა სტატიებში უმარტივესი მაგალითი. ყველა ანონიმურ მომხმარებელზე წვდომის აკრძალვის მიზნით, შეგიძლიათ განსაზღვროთ შემდეგი წესი:

    ამ შემთხვევაში, კითხვის ნიშანი (?) არის ბუნების სიმბოლო, რომელიც წარმოადგენს ყველა მომხმარებელს უცნობი იდენტობის მქონე. ეს წესი თითქმის ყოველთვის გამოიყენება ავთენტიფიკაციის სცენარებში. ეს გამოწვეულია სხვა ცნობილ მომხმარებლებთან წვდომაზე უარის თქმის შეუძლებლობის გამო, თუ პირველ რიგში არ აიძულოთ ყველას საკუთარი თავის ავთენტიფიკაცია.

    თქვენ შეგიძლიათ გამოიყენოთ დამატებითი სიმბოლო, ვარსკვლავი (*), რომელიც წარმოადგენს ყველა მომხმარებელს. მაგალითად, შემდეგი განყოფილება იძლევა წვდომას ავტორიზებულ და ანონიმურ მომხმარებლებს:

    ეს წესი იშვიათად არის საჭირო, რადგან ის უკვე არის machine.config ფაილში. მას შემდეგ, რაც ASP.NET გამოიყენებს ყველა წესს web.config ფაილიდან, ის იყენებს წესებს machine.config-დან. შედეგად, ნებისმიერი მომხმარებელი, რომელსაც აშკარად ეკრძალება წვდომა, ავტომატურად იძენს მას.

    ახლა ვნახოთ, რა მოხდება, თუ ერთზე მეტ წესს დავამატებთ განყოფილებას:

    წესების შეფასებისას ASP.NET ასკანირებს სიას ზემოდან ქვემოდან. როგორც კი იპოვის მოქმედ წესს, ძიება ჩერდება. ამიტომ, წინა შემთხვევაში დაადგენს, რომ წესი ვრცელდება მიმდინარე მოთხოვნაზე და არ გაითვალისწინებს მეორე სტრიქონს. შედეგად, ეს წესი საშუალებას მისცემს ყველა მომხმარებელს წვდომას. თუმცა, თუ ორი ხაზი შეიცვლება, მაშინ წვდომა აკრძალული იქნება ანონიმური მომხმარებლებისთვის (პირველი ხაზის წესის მიხედვით) და ყველა დანარჩენისთვის (მეორე ხაზის წესის მიხედვით).

    როდესაც ავტორიზაციის წესები ემატება ვებ აპლიკაციის root დირექტორიას web.config ფაილს, ისინი ავტომატურად გამოიყენება ყველა ვებ რესურსზე, რომელიც აპლიკაციის ნაწილია. თუ ანონიმურ მომხმარებლებს არ აქვთ შესვლის უფლება, ASP.NET შეამოწმებს ავტორიზაციის მეთოდს. თუ არჩეულია ფორმების ავთენტიფიკაცია, ASP.NET მომხმარებელს გადამისამართებს რეგისტრაციის გვერდზე.

    შემდეგ განყოფილებებში შეიტყობთ უფრო მეტს ჯარიმა დაყენებაავტორიზაციის წესები, რათა უფრო ზუსტად განისაზღვროს მათი ფარგლები.

    წვდომის კონფიგურაცია კონკრეტული მომხმარებლებისთვის

    წესები სულაც არ მოითხოვს სიმბოლოების ვარსკვლავის ან კითხვის ნიშნის გამოყენებას. ამის ნაცვლად, მათ შეუძლიათ კონკრეტულად მიუთითონ მომხმარებლის სახელი ან მძიმით გამოყოფილი მომხმარებლის სახელების სია.

    მაგალითად, შემდეგი ავტორიზაციის წესი კონკრეტულად ზღუდავს წვდომას სამ მომხმარებელს. ეს მომხმარებლები ვერ შეძლებენ წვდომას გვერდებზე, რომლებიც დირექტორიაშია web.config ფაილით, რომელიც შეიცავს ამ ჩანაწერებს. ყველა სხვა ავტორიზებული მომხმარებელი შეძლებს ამ გვერდებზე წვდომას:

    თქვენ ასევე შეგიძლიათ განსაზღვროთ მძიმით გამოყოფილი სახელების სია და უარყოთ წვდომა მრავალ მომხმარებელზე ერთდროულად. ქვემოთ მოცემულია წინა მაგალითის ექვივალენტური ვერსია, რომელიც იყენებს ავტორიზაციის მხოლოდ ორ წესს:

    გაითვალისწინეთ, რომ ორივე შემთხვევაში სიაში მოცემული სამი მომხმარებელი არ არის მნიშვნელოვანი. თუმცა, მნიშვნელოვანია, რომ ამ მომხმარებლებზე წვდომის უარყოფა წინ უსწრებს წესს.

    უსაფრთხო აპლიკაციების შექმნისას ხშირად სჯობს ცალსახად დაუშვათ წვდომა გარკვეული მომხმარებლებიდა ჯგუფები, შემდეგ კი უარყოს ყველა სხვა (იმის ნაცვლად, რომ უარი თქვან წვდომაზე კონკრეტულ მომხმარებლებზე, როგორც წინა მაგალითებში). ქვემოთ მოცემულია ავტორიზაციის წესების მაგალითი, რომელიც ცალსახად იძლევა წვდომას ორ მომხმარებელს. ყველა სხვა მომხმარებლის მოთხოვნა არ დაკმაყოფილდება, მიუხედავად იმისა, რომ ისინი დამოწმებულია:

    ყურადღება უნდა მიაქციოთ ერთ დეტალს. ამ მაგალითებში მომხმარებლის სახელის ფორმატი ითვალისწინებს ავთენტიფიკაციას. ამ ავთენტიფიკაციით, მომხმარებლის სახელი ენიჭება RedirectFromLoginPage() მეთოდის გამოძახებისას. ამ დროს UrlAuthorizationModule ასევე გამოიყენებს ამ სახელს და შეამოწმებს მას ავტორიზაციის წესების სიაში.

    აკონტროლეთ წვდომა კონკრეტულ დირექტორიებზე

    განაცხადის დიზაინის საერთო გადაწყვეტილებაა ფაილების განთავსება, რომლებიც საჭიროებენ ავთენტიფიკაციას ცალკე დირექტორიაში. მადლობა კონფიგურაციის ფაილები ASP.NET, ამ მიდგომის განხორციელება მარტივია. დატოვე ელემენტი x.UserName == name);

    var რესურსი = resourceRepository.Find(id);

    if (resource.UserId != user.UserId) ( გადაყარეთ ახალი HttpResponseException(HttpStatusCode.Unauthorized); ) დააბრუნეთ რესურსი;

    )

    სადაც მომხმარებლის ავთენტიფიკაცია მოხდა ზოგიერთი მექანიკოსის მიერ.

    ახლა ვთქვათ, რომ მეც მინდა ადმინისტრატორს მსგავს მომხმარებელს ჰქონდეს საბოლოო წერტილის მოხმარების უფლება (იგივე ID-ით). ამ მომხმარებელს არ აქვს პირდაპირი კავშირი რესურსთან, მაგრამ აქვს ავტორიზაცია მისი ტიპის (ან როლის) გამო. ეს შეიძლება გადაწყდეს უბრალოდ შემოწმებით არის თუ არა მომხმარებელი ადმინისტრატორის ტიპისა და რესურსის დაბრუნებით.

    არის თუ არა ამის ცენტრალიზაციის საშუალება, რომ ყველა მოქმედებაში არ მომიწიოს ავტორიზაციის კოდის დაწერა?

    რედაქტირება პასუხებიდან გამომდინარე, ვფიქრობ, უნდა დავაზუსტო ჩემი შეკითხვა. რასაც მე ნამდვილად ვაკეთებ არის მექანიზმი, რომელიც საშუალებას გაძლევთ გქონდეთ რესურსზე დაფუძნებული ავტორიზაცია, მაგრამ ამავე დროს საშუალებას აძლევს ზოგიერთ მომხმარებელს ასევე გამოიყენოს იგივე საბოლოო წერტილი და იგივე რესურსი. ქვემოთ მოცემული ქმედება ამის საშუალებას მოგცემთ ამ კონკრეტული საბოლოო წერტილისთვის და ამ კონკრეტული როლისთვის (ადმინისტრატორი).საჯარო რესურსი GetResource(int id) ( string name = Thread.CurrentPrincipal.Identity.Name; var user = userRepository.SingleOrDefault(x => x.UserName == სახელი); var რესურსი = resourceRepository.Find(id); თუ (! user.Roles.Any(x => x.RoleName == "Admin" || resource.UserId != user.UserId) ( გადაყარეთ ახალი HttpResponseException(HttpStatusCode.Unauthorized); ) დააბრუნეთ რესურსი;

    რასაც ვიღებ არის

    რესურსებზე დაფუძნებული ავტორიზაციისთვის, მე გირჩევთ გამოიყენოთ პრეტენზიებზე დაფუძნებული ID და ჩასვათ მომხმარებლის ID, როგორც პრეტენზია. დაწერეთ გაფართოების მეთოდი ინდივიდუალური პრეტენზიის წასაკითხად. ასე რომ, ნიმუში კოდი ასე გამოიყურება:

    საჯარო რესურსი GetResource(int id) ( var resource = resourceRepository.Find(id); if (resource.UserId != User.Identity.GetUserId()) ( გადაყარეთ ახალი HttpResponseException(HttpStatusCode.Unauthorized); ) დააბრუნეთ რესურსი; )

    თუ გსურთ კიდევ უფრო გაამარტივოთ კოდი, შეგიძლიათ დაწეროთ UserRepository, რომელმაც იცის მომხმარებლის მონაცემები და რესურსების საცავი კოდის ცენტრალიზებისთვის. კოდი ასე გამოიყურება:

    საჯარო რესურსი GetResource(int id) ( დააბრუნეთ User.Identity.GetUserRepository().FindResource(id); )

    როლებზე დაფუძნებული ავტორიზაციისთვის, AuthorizeAttribute იქნება საუკეთესო ადგილი მის დასამუშავებლად და უმჯობესია გამოიყენოთ ცალკე მოქმედება ან კონტროლერი ამისათვის.

    საჯარო რესურსი GetResourceByAdmin(int id) ( return resourceRepository.Find(id); )

    [რედაქტირება] თუ OP-ს სურს გამოიყენოს ერთი მოქმედება სამუშაოდ სხვადასხვა ტიპისმომხმარებლებო, მე პირადად მირჩევნია მომხმარებელთა საცავის ქარხნის გამოყენება. მოქმედების კოდი:

    საჯარო რესურსი GetResource(int id) ( დაბრუნება User.GetUserRepository().FindResource(id); )

    გაფართოების მეთოდი იქნება:

    საჯარო სტატიკური IUserRepository GetUserRepository(ეს IP-ძირითადი) ( var resourceRepository = new ResourceRepository(); bool isAdmin = principal.IsInRole("Admin"); if (isAdmin) ( return new AdminRespository(resourceRepository (resourceRepository(newRepository)) .იდენტობა, რესურსის საცავი);

    მიზეზი, რის გამოც არ მინდა გამოვიყენო AuthorizeAttribute თითოეული რესურსის ავთენტურობის შესამოწმებლად, არის ის, რომ სხვადასხვა რესურსს შეიძლება ჰქონდეს განსხვავებული კოდი საკუთრების დასადასტურებლად, ძნელია კოდის ცენტრალიზაცია ერთ ატრიბუტში და საჭიროებს დამატებით DB ოპერაციებს, რაც არ არის ნამდვილად საჭირო. კიდევ ერთი საკითხია ის, რომ AuthroizeAttribute ხდება პარამეტრების დაკავშირებამდე, ასე რომ თქვენ უნდა დარწმუნდეთ, რომ მოქმედების პარამეტრი მოდის მარშრუტის მონაცემებიდან. წინააღმდეგ შემთხვევაში, მაგალითად, თქვენ ვერ შეძლებთ პარამეტრის მნიშვნელობას შეტყობინების ტექსტიდან.

    თქვენ უნდა გაატაროთ თქვენი ავტორიზაცია. გსურთ გადაიტანოთ ავტორიზაციის მთელი ლოგიკა ცალკეულ ფენაში ან სერვისში.

    არსებობს რამდენიმე ჩარჩო - სხვადასხვა ენაზე - რომელიც საშუალებას გაძლევთ ამის გაკეთება. .NET სამყაროში, როგორც სხვა პასუხებშია შემოთავაზებული, თქვენ გაქვთ მოთხოვნებზე დაფუძნებული ავტორიზაცია. Microsoft-ს აქვს შესანიშნავი სტატია ამის შესახებ.

    • სტანდარტული არქიტექტურა პოლიტიკის გადაწყვეტილების პუნქტის კონცეფციით (PDP არის თქვენი ავტორიზაციის სერვისი), რომელიც შეიძლება იყოს დიახ/არა გადაწყვეტილებები
    • ავტორიზაციის ლოგიკის გამოხატვის სტანდარტული ენა ნებისმიერი რაოდენობის პარამეტრის/ატრიბუტის გამოყენებით, მომხმარებლის ატრიბუტებისა და რესურსების ინფორმაციის ჩათვლით.
    • მოთხოვნა/პასუხის სქემა თქვენი ავტორიზაციის კითხვების PDP-სთვის გაგზავნისთვის.

    თუ თქვენს მაგალითზე გადავალთ, თქვენ გექნებათ რაღაც სტრიქონი:

    საჯარო რესურსი GetResource(int id) ( var resource = resourceRepository.Find(id); if (isAuthorized(User.Identity,resource)) ( გადაყარეთ ახალი HttpResponseException(HttpStatusCode.Unauthorized); ) დააბრუნეთ რესურსი; ) public bool isAuthorized(User u , რესურსი r)( // შექმენით XACML მოთხოვნა აქ // დარეკეთ PDP-ზე // დააბრუნეთ ლოგიკური გადაწყვეტილება)

    თქვენი PDP შეიცავს შემდეგ წესებს:

    • მომხმარებელს შეუძლია შეასრულოს ქმედება == ნახვა რესურსზე, თუ და მხოლოდ იმ შემთხვევაში, თუ resource.owner == user.id
    • == ადმინისტრატორის როლის მქონე მომხმარებელს შეუძლია შეასრულოს == მოქმედება რესურსზე.

    XACML-ის უპირატესობა ის არის, რომ თქვენ შეგიძლიათ შექმნათ თქვენი ავტორიზაციის წესები/ლოგიკა თქვენი კოდისგან დამოუკიდებლად. ეს ნიშნავს, რომ თქვენ არ გჭირდებათ თქვენი აპლიკაციის კოდის შეხება ყოველ ჯერზე, როცა ლოგიკა იცვლება. XACML ასევე შეუძლია გაუმკლავდეს მეტ პარამეტრს/ატრიბუტს - მაგალითად, მოწყობილობის ID, IP მისამართი, დღის დრო... და ბოლოს, XACML არ არის სპეციფიკური .NET-ისთვის. ის მუშაობს სხვადასხვა ჩარჩოებისთვის.

    მე შევხედავდი მორგებული System.Web.Http.AuthorizeAttribute-ის განხორციელებას, რომელიც შეგიძლიათ მიმართოთ მოქმედებებს, რომლებსაც ესაჭიროებათ ავტორიზაციის კონკრეტული წესი. მომხმარებლის ავტორიზაციისას, თქვენ შეგიძლიათ დაუშვათ წვდომა, თუ მომხმარებელი არის ადმინისტრატორების ჯგუფის წევრი, ან თუ ის არის რესურსის ავტორი.

    შეცვლა:

    OP-ის რედაქტირებიდან გამომდინარე, ნება მომეცით გავაფართოვოთ რასაც ვამბობ. თუ თქვენ უგულებელყოფთ AuthorizeAttribute-ს, შეგიძლიათ დაამატოთ ლოგიკა, როგორიცაა:

    საჯარო კლასი AuthorizeAdminsAndAuthors: System.Web.Http.AuthorizeAttribute (დაცული უგულებელყოფა bool IsAuthorized(HttpActionContext actionContext) (აბრუნებს currentUser.IsInRole("Admins") || IsCurrentUserAuthorOfPostolt(IsCurrentUserAuthorOfPostoltA); ttpActionContext მოქმედების კონტექსტი) ( // მიიღეთ id რესურსისთვის actionContext-დან // მოძებნეთ, თუ მომხმარებელი არის ამ პოსტის ავტორი, დააბრუნეთ true)

    ეს არის ფსევდო კოდი, მაგრამ იდეა უნდა გავრცელდეს. თუ თქვენ გაქვთ ერთი AuthorizeAttribute, რომელიც განსაზღვრავს ავტორიზაციას თქვენი მოთხოვნებიდან გამომდინარე: მიმდინარე მოთხოვნა არის პოსტის ავტორის ან ადმინისტრატორისგან, მაშინ შეგიძლიათ გამოიყენოთ AuthorizeAdminsAndAuthors ატრიბუტი ნებისმიერ რესურსზე, სადაც საჭიროა ავტორიზაციის ეს დონე. ასე რომ, თქვენი რესურსი ასე გამოიყურება:

    საჯარო რესურსი GetResource(int id) ( var resource = resourceRepository.Find(id); დაბრუნების რესურსი; )



    რაიმე შეკითხვა?

    შეატყობინეთ შეცდომას

    ტექსტი, რომელიც გაეგზავნება ჩვენს რედაქტორებს: