Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 跨请求持久化新声明_C#_.net_Owin_Claims Based Identity_Ws Federation - Fatal编程技术网

C# 跨请求持久化新声明

C# 跨请求持久化新声明,c#,.net,owin,claims-based-identity,ws-federation,C#,.net,Owin,Claims Based Identity,Ws Federation,我如何添加新的声明,使它们在cookie过期之前一直存在于请求中 我正在使用OWIN中间件,即本地身份验证来验证登录系统的用户 登录部分成功了,我将角色添加到ws-federation提供的用户声明中,以帮助授权用户使用某些操作方法。 在登录控制器时,我编写了以下内容来添加角色: string[] roles = { "Role1", "Role2" }; var identity = new ClaimsIdentity(User.Identity); foreach (var role i

我如何添加新的声明,使它们在cookie过期之前一直存在于请求中

我正在使用OWIN中间件,即本地身份验证来验证登录系统的用户

登录部分成功了,我将角色添加到ws-federation提供的用户声明中,以帮助授权用户使用某些操作方法。 在登录控制器时,我编写了以下内容来添加角色:

string[] roles = { "Role1", "Role2" };

var identity = new ClaimsIdentity(User.Identity);
foreach (var role in roles)
{
    identity.AddClaim(new Claim(ClaimTypes.Role, role));
}

var authenticationManager = HttpContext.GetOwinContext().Authentication;

authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant
                             (new ClaimsPrincipal(identity),
                              new AuthenticationProperties { IsPersistent = true });

但是,当我在下一个请求中检查声明时,我看不到角色声明。

成功身份验证后,我相信您添加了自定义声明(通常在成功身份验证后添加到某些事件处理程序)。现在,为了在后续请求中保留该信息,您需要在管道中的身份验证owin之前使用CookieAuthentication中间件

工作原理:

在首次成功身份验证并添加自定义声明后,声明将转换为某种身份验证cookie并发送回客户端。后续请求将携带此验证cookie。查找auth cookie的cookie身份验证中间件将使用从cookie获得的声明设置Thread.CurrentPriciple

在首次请求期间,当cookie中间件确实看到任何auth cookie时,它会将请求传递给管道中的下一个中间件(在您的情况下为验证owin),以质询用户登录

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

app.UseCookieAuthentication(new CookieAuthenticationOptions()
            {

                AuthenticationType = "Cookies",
                AuthenticationMode= AuthenticationMode.Active,
                CookieName="XXXXX",
                CookieDomain= _cookiedomain,
                /* you can go with default cookie encryption also */
                TicketDataFormat = new TicketDataFormat(_x509DataProtector),
                SlidingExpiration = true,
                CookieSecure = CookieSecureOption.Always,
            });


app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {

                ClientId = _clientID,
                Authority = _authority,
                RedirectUri = _redirectUri,
                UseTokenLifetime = false,

                Notifications = new OpenIdConnectAuthenticationNotifications
                {

                    SecurityTokenValidated = SecurityTokenValidated,

                    AuthenticationFailed = (context) =>
                    {
                        /* your logic to handle failure*/
                    }
                },

                TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
                {
                    ValidIssuers = _validIssuers,
                    ValidateIssuer = _isValidIssuers,
                }
            });
编辑:(附加信息)
与上面的代码基本相同的代码也适用于ws-federation,具有相同的逻辑和所有功能

SecurityTokenValidated = notification =>
{
    ClaimsIdentity identity = notification.AuthenticationTicket.Identity;
    string[] roles = { "Role1", "Role2" };
    foreach (var role in roles)
    {
        identity.AddClaim(new Claim(ClaimTypes.Role, role));
    }
    return Task.FromResult(0);
}

您需要使用与您在
启动.ConfigureAuth
中使用的相同的
身份验证类型。例如:

Startup.ConfigureAuth
中:

app.UseCookieAuthentication(new CookieAuthenticationOptions {
  AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
  //....
});
在您的登录代码中(问题中提供):

或者确保
User.Identity
具有相同的
AuthenticationType
,并且您可以像以前那样使用它:

var identity = new ClaimsIdentity(User.Identity);
现在重要的一点是,对于登录,您应该在使用之前添加声明,而不是之后。大概是这样的:

HttpContext.GetOwinContext().Authentication.SignIn(identity);
您可以在登录后添加声明,但在创建cookie之后,您将立即修改cookie,这是没有效率的。如果在其他代码中需要修改声明,则可以使用与代码类似的内容,但必须从
Current
获取上下文:

HttpContext.Current.GetOwinContext().Authentication.AuthenticationResponseGrant =
    new AuthenticationResponseGrant(new ClaimsPrincipal(identity),
                                    new AuthenticationProperties { IsPersistent = true });

因此,您可以通过简单地添加上述
Current
来修复代码,但这对登录代码来说并不有效,最好将声明传递给
SignIn
函数。

您可以在WEB API C#(SOAP)(存储过程)中执行以下操作

public override异步任务GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext)
{
context.OwinContext.Response.Headers.Add(“访问控制允许来源”,新[]{“*”});
LoginModel模型=新LoginModel();
//验证用户凭据并获取用户角色(返回列表角色)
//瓦利达尔·拉斯克里德夏莱斯·德乌萨里奥和奥巴顿·德乌萨里奥
var user=model.user=\u serviceusario.obteneusario(context.UserName,context.Password);
if(user==null)
{
上下文。SetError(“无效的授权”,“合同编号”no son correctoros.cod 01”);
返回;
}
var stringRoles=user.Roles.Replace(“,”);//这取决于如何从数据库中获取它们
string[]roles=stringRoles.Split(',');//这取决于如何从数据库中获取它们
var identity=newclaimsidentity(context.Options.AuthenticationType);
foreach(角色中的var Rol)
{
identity.AddClaim(新声明(ClaimTypes.Role,Rol));
}
AddClaim(新声明(ClaimTypes.Name,context.UserName));
identity.AddClaim(新的索赔(ClaimTypes.Email,user.Correo));
identity.AddClaim(新声明(ClaimTypes.MobilePhone,user.Celular));
identity.AddClaim(新声明(“FullName”,user.FullName));//新声明类型
identity.AddClaim(新索赔(“Empresa”,user.Empresa));//新索赔类型
identity.AddClaim(新声明(“ConnectionStringsName”,user.ConnectionStringsName));//新声明类型
//为客户端添加用户信息
var properties=newauthenticationproperties(新字典
{
{“userName”,user.NombreUsuario},
{“FullName”,user.FullName},
{“EmpresaName”,user.Empresa}
});
//结束
var票证=新的身份验证票证(身份、属性);
上下文。已验证(票证);
}

我理解你解释的一些内容,但你能再解释一下吗?可能有一些代码?我对ADFSAfter edit不太熟悉:那么,你是说我需要在使用app.UseWsFederationAuthentication时在Startup.Auth.cs中添加我的自定义声明?我用我最近使用的一些代码片段更新了答案。@Sanketh.K.Jain:所以你的库应该有一些事件(比如SecurityTokenValidated,您可以订阅并添加自定义索赔。您可能会获得更多上下文信息
HttpContext.Current.GetOwinContext().Authentication.AuthenticationResponseGrant =
    new AuthenticationResponseGrant(new ClaimsPrincipal(identity),
                                    new AuthenticationProperties { IsPersistent = true });
    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
        LoginModel model = new LoginModel();
        //validate user credentials and obtain user roles (return List Roles) 
        //validar las credenciales de usuario y obtener roles de usuario
        var user = model.User = _serviceUsuario.ObtenerUsuario(context.UserName, context.Password);
        if (user == null)
        {
            context.SetError("invalid_grant", "El nombre de usuario o la contraseña no son correctos.cod 01");
            return;
        }

        var stringRoles = user.Roles.Replace(" ", "");//It depends on how you bring them from your DB
        string[] roles = stringRoles.Split(',');//It depends on how you bring them from your DB

        var identity = new ClaimsIdentity(context.Options.AuthenticationType);          
        foreach(var Rol in roles)
        {
            identity.AddClaim(new Claim(ClaimTypes.Role, Rol));
        }
        identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
        identity.AddClaim(new Claim(ClaimTypes.Email, user.Correo));
        identity.AddClaim(new Claim(ClaimTypes.MobilePhone, user.Celular));
        identity.AddClaim(new Claim("FullName", user.FullName));//new ClaimTypes
        identity.AddClaim(new Claim("Empresa", user.Empresa));//new ClaimTypes
        identity.AddClaim(new Claim("ConnectionStringsName", user.ConnectionStringsName));//new ClaimTypes
//add user information for the client
        var properties = new AuthenticationProperties(new Dictionary<string, string>
        {
            { "userName",user.NombreUsuario },
            { "FullName",user.FullName },
            { "EmpresaName",user.Empresa }
        });
//end
        var ticket = new AuthenticationTicket(identity, properties);
       context.Validated(ticket);
    }