Умный способ авторизации пользователя (без создания таблицы и т. Д. c.) В ASP. NET MVC - PullRequest
2 голосов
/ 01 апреля 2020

Я использую внешнего провайдера для аутентификации пользователя в моем приложении ASP. NET MVC без каких-либо проблем. Однако мне также необходимо авторизовать пользователей, чтобы предотвратить прямой доступ или доступ с истекшим сроком действия (сеанс 2 минуты). Я использовал ASP. NET Identity и раньше, но на этот раз мне не нужно оставлять ни пользователей, ни роли на столе, и по этой причине мне нужен быстрый и хороший способ решения этой проблемы. Итак, как я могу предотвратить доступ пользователя к странице In dex моего приложения без проверки подлинности провайдером, которого я использую. Аналогичным образом мне также необходимо проверить, прошло ли более 2 минут после последнего действия пользователя, и в такой ситуации мне нужно перенаправить пользователя на страницу входа. Я пытался использовать OWIN Cook ie, но, к сожалению, я не могу выйти из системы, используя как минимум 10 различных подходов :(

Запуск:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);
    }

    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),

            //other options
            ExpireTimeSpan = TimeSpan.FromMinutes(1)
            //Provider = new CookieAuthenticationProvider(),
            //CookieName = "MyCookieName",
            //CookieHttpOnly = true
        });
    }
}

Контроллер:

[HttpGet]
public ActionResult Login(string code)
{
    //At this stage I want to force user to sign out, but none of the following methods work

    //method 1
    HttpContext.GetOwinContext().Authentication.SignOut("ApplicationCookie");

    //method 2
    var ctx = Request.GetOwinContext();
    var authManager = ctx.Authentication;
    authManager.SignOut("ApplicationCookie");
    //or        
    //authManager.SignOut();

    //method 3
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);

    //method 4 (using only one of them at a time)
    Request.GetOwinContext().Authentication.SignOut();
    Request.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);
    HttpContext.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);


    //check session
    var isAuthenticated = HttpContext.GetOwinContext().Authentication.User.Identity.IsAuthenticated; // >>> always returns true
    string tc = HttpContext.GetOwinContext().Authentication.User.Identity.Name; // >>> always returns name value


    //if user is authenticated via OAuth2.0
    if (user.isAuthenticated)
    {
        var claims = new[] {
        new Claim(ClaimTypes.Name, user.Name)
    };

        var identity = new ClaimsIdentity(claims, "ApplicationCookie");

        //// Add roles into claims
        //var roles = _roleService.GetByUserId(user.Id);
        //if (roles.Any())
        //{
        //    var roleClaims = roles.Select(r => new Claim(ClaimTypes.Role, r.Name));
        //    identity.AddClaims(roleClaims);
        //}

        var context = Request.GetOwinContext();
        var authManager = context.Authentication;

        authManager.SignIn(new AuthenticationProperties
        { IsPersistent = false }, identity); // ??? I am not sure if IsPersistent should be true ? 

        return View();
    }

    // login failed
    return RedirectToAction("Account", "Login");
}

Ответы [ 4 ]

1 голос
/ 01 апреля 2020

Вы можете использовать Entry Framwork, JSON Веб-токен (JWT) и Заявки . Действительно легко ограничить количество времени (дни, часы, минуты), когда вы хотите, чтобы пользователь имел доступ к разделу ваших контроллеров с JWT.

Вы можете ограничить время, к которому JWT имеет доступ, используя объект Expires в SecurityTokenDescriptor. Так что в вашем случае я бы сделал следующее:

var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim(ClaimTypes.Name, user.Id.ToString())
                }),
                Expires = DateTime.UtcNow.AddMinutes(2),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };

Есть несколько замечательных ПОЛНЫХ примеров, сделанных Джейсоном Уотмором для. NET Ядро с Role Based Auth и Secure Auth для хешированного пароля в базе данных . Не уверен, какую библиотеку вы используете, поэтому, если это вам не поможет, я помогу вам, если вы укажете.

1 голос
/ 01 апреля 2020

Я AmirReza, о котором вы говорили ранее.

Редактировать

Чтобы MVC понял что-нибудь о вашем JWT, вы должны сказать это: -). Сначала установите пакет Jwt из nuget:

Install-Package Microsoft.Owin.Security.Jwt Затем откройте файл Startup.cs и добавьте новую функцию, которая сообщит MVC, как использовать JWT. Основы вашего запуска будут выглядеть примерно так:

    using System.Configuration;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.DataHandler.Encoder;
using Microsoft.Owin.Security.Jwt;
using Owin;
[assembly: OwinStartupAttribute(typeof(TOMS.Frontend.Startup))]
namespace TOMS.Frontend {
 public partial class Startup 
{ 
public void Configuration(IAppBuilder app) 
{ 
ConfigureAuth(app);
ConfigureOAuthTokenConsumption(app);
} 
private void ConfigureOAuthTokenConsumption(IAppBuilder app) 
{ 
var issuer = ConfigurationManager.AppSettings["Issuer"];
var audienceId = ConfigurationManager.AppSettings["AudienceId"];
var audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["AudienceSecret"]);

Вы заметите, что я размещаю эмитента, audienceId и audienceSecret в моем файле Web.config. (Эти значения должны соответствовать значениям на вашем сервере ресурсов). Кроме того, вы можете убедиться, что у вас запущен обновленный System.IdentityModel.Tokens.Jwt:

Пакет обновлений System.IdentityModel.Tokens.Jwt С этими настройками вы можете украсить свое действие контроллера с атрибутом [Authorize] и играть в мяч.

ОБНОВЛЕНИЕ Кстати, если вы захотите sh добавить значения в ваш файл web.config, чтобы получить их, как я делал выше; просто добавьте их под AppSettings:

<configuration> <appSettings> <add key="Issuer" value="YOUR_ISSUER" /> <add key="AudienceId" value="YOUR_AUDIENCEID" /> <add key="AudienceSecret" value="YOUR_AUDIENCESECRET" /> </appSettings> </configuration>
1 голос
/ 01 апреля 2020

Вам необходимо установить атрибут [Authorize] для действия и / или контроллера.

А сеанс длится только 2 минуты. Вы можете поместить метку времени в сеансную кухню ie, когда пользователь войдет в систему, а затем создать промежуточное ПО для проверки значения сеанса при каждом выполнении действия. Если значение сеанса старше 2 минут, выйдите из системы.

Как использовать сеанс:

В файле запуска добавьте:

services.AddSession(options =>
{
   options.Cookie.SecurePolicy = CookieSecurePolicy.Always; 
});

и

app.UseSession();
//middleware for checking the 2 minute limit
app.UseMiddleware<SignoutMiddleware>();

Добавьте сеанс везде, где пользователь вошел в систему:

HttpContext.Session.SetString(subjectId, DateTime.Now);

Промежуточное программное обеспечение:

public class SignoutMiddleware
{
    private readonly RequestDelegate _next;

    public SignoutMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {

        var sessionExpire = context.Session.GetString(context.User.GetSubjectId());
        //Do some logic here
        await _next.Invoke(context);
    }
}

Что касается того, что ваш код делает для входа в систему, вам, вероятно, нужно изменить некоторые , Но должно быть много уроков, если вы просто гуглите:)

0 голосов
/ 03 апреля 2020

Наконец-то я исправил проблему с помощью OWIN cook ie аутентификация . Вот код для тех, кому может понадобиться использовать OWIN cook ie аутентификация на ASP. NET MVC.

С другой стороны, я действительно хотел бы интегрировать JWT в мой проект ASP. NET MVC, но, к сожалению, не смог этого сделать. Тем не менее, большое спасибо и проголосовали за ответы, которые также полезны для меня.

Запуск:

public void Configuration(IAppBuilder app)
{
    ConfigureAuth(app);
}

public void ConfigureAuth(IAppBuilder app)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        LogoutPath = new PathString("/Account/LogOff"),
        ExpireTimeSpan = TimeSpan.FromMinutes(5),
        SlidingExpiration = true,
        Provider = new CookieAuthenticationProvider(),
        CookieName = "YOUR_COOKIE_NAME",
        CookieHttpOnly = true,
        // !!! Using this setting "Always" causing "302 Redirect..." error while ddebugging >>>
        CookieSecure = CookieSecureOption.SameAsRequest 
    });
}

AccountController:

public ActionResult Login()
{
    //authenticate user
    var user = db.GetUser("John");

    if (user != null)
    {
        var claims = new[] {
            new Claim(ClaimTypes.Name, user.Name),
            new Claim(ClaimTypes.Email, user.Email)
            //you can add more claims
        };

        var identity = new ClaimsIdentity(claims, "ApplicationCookie");

        // Add roles into claims
        var roles = _roleService.GetByUserId(user.Id);
        if (roles.Any())
        {
            var roleClaims = roles.Select(r => new Claim(ClaimTypes.Role, r.Name));
            identity.AddClaims(roleClaims);
        }

        var context = Request.GetOwinContext();
        var authManager = context.Authentication;

        authManager.SignIn(new AuthenticationProperties
            { IsPersistent = true }, identity);

        return RedirectToAction("Index", "Home");
    }
    // login failed. 
    return RedirectToAction("Login", "Account");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...