Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.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
<img src="//i.stack.imgur.com/WM7S8.png" height="16" width="18" alt="" class="sponsor tag img">servicestack 使用自托管Servicestack的Aurelia身份验证_<img Src="//i.stack.imgur.com/WM7S8.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">servicestack_Aurelia - Fatal编程技术网 servicestack 使用自托管Servicestack的Aurelia身份验证,servicestack,aurelia,servicestack,Aurelia" /> servicestack 使用自托管Servicestack的Aurelia身份验证,servicestack,aurelia,servicestack,Aurelia" />

servicestack 使用自托管Servicestack的Aurelia身份验证

servicestack 使用自托管Servicestack的Aurelia身份验证,servicestack,aurelia,servicestack,Aurelia,也许我使用了错误的搜索词,但我找不到有关如何获得Aurelia身份验证以更好地使用ServiceStack的任何信息。我非常不熟悉网站使用的超级复杂的身份验证方案,所以如果我尝试一些毫无意义的东西,可能是因为我感到困惑。我试图做的是允许我的用户使用他们的windows凭据登录,但不允许我的web应用需要IIS进行部署(自托管)。因此,我需要传输一个用户名/密码,并让servicestack返回一些Aurelia可以使用的东西来存储经过身份验证的会话信息。现在我倾向于使用JWT 以下是我在客户端的

也许我使用了错误的搜索词,但我找不到有关如何获得Aurelia身份验证以更好地使用ServiceStack的任何信息。我非常不熟悉网站使用的超级复杂的身份验证方案,所以如果我尝试一些毫无意义的东西,可能是因为我感到困惑。我试图做的是允许我的用户使用他们的windows凭据登录,但不允许我的web应用需要IIS进行部署(自托管)。因此,我需要传输一个用户名/密码,并让servicestack返回一些Aurelia可以使用的东西来存储经过身份验证的会话信息。现在我倾向于使用JWT

以下是我在客户端的内容(Aurelia):

梅因酒店

import { Aurelia } from 'aurelia-framework';
import 'src/helpers/exceptionHelpers'
import config from "./auth-config";

export function configure(aurelia: Aurelia) {
    aurelia.use
        .standardConfiguration()
        .feature('src/resources')
        .developmentLogging()
        .plugin('aurelia-dialog')
        .plugin('aurelia-api', config => {
            // Register an authentication hosts
            config.registerEndpoint('auth', 'http://localhost:7987/auth/');
        })
        .plugin('aurelia-authentication', (baseConfig) => {
            baseConfig.configure(config);
        });

    aurelia.start().then(x => x.setRoot('src/app'));
}
auth-config.ts

var config = {
    endpoint: 'auth',             // use 'auth' endpoint for the auth server
    configureEndpoints: ['auth'], // add Authorization header to 'auth' endpoint

    // The API specifies that new users register at the POST /users enpoint
    signupUrl: null,
    // The API endpoint used in profile requests (inc. `find/get` and `update`)
    profileUrl: null,
    // Logins happen at the POST /sessions/create endpoint
    loginUrl: '',
    // The API serves its tokens with a key of id_token which differs from
    // aurelia-auth's standard
    accessTokenName: 'BearerToken',
    // Once logged in, we want to redirect the user to the welcome view
    loginRedirect: '#/pending',
    // The SPA url to which the user is redirected after a successful logout
    logoutRedirect: '#/login',
    // The SPA route used when an unauthenticated user tries to access an SPA page that requires authentication
    loginRoute : '#/help'
};

export default config;
login.ts

import { AuthService } from 'aurelia-authentication';
import { inject, computedFrom } from 'aurelia-framework';

@inject(AuthService)
export class Login {
    heading: string;
    auth: AuthService;
    userName: string;
    password: string;

    constructor(authService) {
        this.auth = authService;
        this.heading = 'Login';
    }

    login() {
        var credentials = {
            username: this.userName,
            password: this.password,
            grant_type: "password"
        };
        return this.auth.login(credentials,
                               { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
        ).then(response => {
                console.log("success logged " + response);
            })
            .catch(err => {
                console.log("login failure");
            });
    }; 
}
AppHost(serviceStack)上的配置:

public override void Configure(容器)
{
var privateKey=RsaUtils.CreatePrivateKeyParams(rsaKeyLength.Bit2048);
var publicKey=privateKey.toPublicsSpaParameters();
var privateKeyXml=privateKey.ToPrivateKeyXml();
var publicKeyXml=privateKey.ToPublicKeyXml();
SetConfig(新主机配置)
{
#如果调试
DebugMode=true,
WebHostPhysicalPath=Path.GetFullPath(Path.Combine(“~”.MapServerPath(),“.”,“.”),
#恩迪夫
});
container.RegisterAs();
Register(newmemorycacheclient{FlushOnDispose=false});
container.RegisterAs();
Add(新建AuthFeature(()=>新建AuthUserSession(),
新[]{
container.Resolve(),
新JwtAuthProvider{
HashAlgorithm=“RS256”,
PrivateKeyXml=PrivateKeyXml,
RequireSecureConnection=false,
}
})
{
HtmlRedirect=“~/#/pending”,
IncludeRegistrationService=false,
IncludeAssignRoleServices=false,
MaxLoginAttents=Settings.Default.MaxLoginAttents
});
}
我在要限制访问的ServiceInterface上具有Authenticate属性

最后,LDAP提供程序:

public class LDAPAuthProvider : CredentialsAuthProvider
{
    private readonly IHoldingsManagerSettings _settings;

    public LDAPAuthProvider(IHoldingsManagerSettings settings)
    {
        _settings = settings;
    }
    public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
    {
        //Check to see if the username/password combo is valid, an exception will be thrown if the username or password is wrong
        try
        {
            var entry = new DirectoryEntry($"LDAP://{_settings.Domain}", userName, password);
            var nativeObject = entry.NativeObject;
            using (var identity = new WindowsIdentity(userName))
            {
                var principal = new WindowsPrincipal(identity);
                return principal.IsInRole(_settings.AdminGroupName);
            }
        }
        catch (Exception)
        {
            //This means the username/password combo failed
            return false;
        }
    }

    public override IHttpResult OnAuthenticated(IServiceBase authService,
                                                IAuthSession session,
                                                IAuthTokens tokens,
                                                Dictionary<string, string> authInfo)
    {
        //Fill IAuthSession with data you want to retrieve in the app eg:
        session.DisplayName = "Testy McTesterson";
        //...

        //Call base method to Save Session and fire Auth/Session callbacks:
        return base.OnAuthenticated(authService, session, tokens, authInfo);

        //Alternatively avoid built-in behavior and explicitly save session with
        //authService.SaveSession(session, SessionExpiry);
        //return null;
    }
}
公共类LDAPAuthProvider:CredentialsAuthProvider
{
专用只读IHoldingsManagerSettings\u设置;
公共LDAPAuthProvider(IHoldingsManagerSettings设置)
{
_设置=设置;
}
公共覆盖bool TryAuthenticate(IServiceBase authService、字符串用户名、字符串密码)
{
//检查用户名/密码组合是否有效,如果用户名或密码错误,将引发异常
尝试
{
var entry=newdirectoryentry($“LDAP://{u settings.Domain}”,用户名,密码);
var nativeObject=entry.nativeObject;
使用(var标识=新的WindowsIdentity(用户名))
{
var principal=新的WindowsPrincipal(标识);
返回principal.IsInRole(_settings.AdminGroupName);
}
}
捕获(例外)
{
//这意味着用户名/密码组合失败
返回false;
}
}
公共覆盖IHTTPRESSLT OnAuthenticated(IServiceBase authService,
第二届会议,
IAuthTokens代币,
字典(authInfo)
{
//使用要在应用程序中检索的数据填充IAuthSession,例如:
session.DisplayName=“Testy McTesterson”;
//...
//调用基本方法保存会话并触发身份验证/会话回调:
返回base.OnAuthenticated(authService、会话、令牌、authInfo);
//或者,避免内置行为,并使用显式保存会话
//SaveSession(session,SessionExpiry);
//返回null;
}
}
到目前为止,当我尝试登录时,我尽量在LDAP提供程序中获取ServiceStack接收请求的信息,身份验证成功,但当请求返回时,aurelia身份验证不喜欢ServiceStack在其会话信息中返回的任何内容的格式

我对这里发生的事情的理解肯定有点偏差。如果有人能为我指出正确的方向,我将非常感激

编辑1

将“accessTokenName”更改为“BealerToken”,似乎至少可以设置有效负载。但是仍然在客户端获得失败的身份验证。还需要弄清楚如何获得Aurelia身份验证以将会话存储在cookie中

编辑2

经过多次调试,似乎一切都正常工作,问题是登录成功后,我被重定向到一个页面,该页面发出一个必须经过身份验证的调用。但是,我在使用servicestack JsonServiceClient传递经过身份验证的Jwt令牌时遇到问题,请参见此处:

事实证明,当您部署到生产环境时,上述LDAPprovider无法按预期方式工作(原因超出了此线程的范围)

如果包含对以下内容的引用:System.DirectoryServices.AccountManagement

并更改以下方法:

public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
    //Check to see if the username/password combo is valid, an exception will be thrown if the username or password is wrong
    try
    {
        var entry = new DirectoryEntry($"LDAP://{_settings.Domain}", userName, password);
        var nativeObject = entry.NativeObject;

        var ctx = new PrincipalContext(ContextType.Domain, _settings.Domain);
        var user = UserPrincipal.FindByIdentity(ctx, userName);
        if (user == null)
        {
            return false;
        }

        var group = GroupPrincipal.FindByIdentity(ctx, _settings.AdminGroupName);
        if (group == null)
        {
            return false;
        }

        return user.IsMemberOf(group);
    }
    catch (Exception)
    {
        //This means the username/password combo failed
        return false;
    }
}
一切都应按预期进行

public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
    //Check to see if the username/password combo is valid, an exception will be thrown if the username or password is wrong
    try
    {
        var entry = new DirectoryEntry($"LDAP://{_settings.Domain}", userName, password);
        var nativeObject = entry.NativeObject;

        var ctx = new PrincipalContext(ContextType.Domain, _settings.Domain);
        var user = UserPrincipal.FindByIdentity(ctx, userName);
        if (user == null)
        {
            return false;
        }

        var group = GroupPrincipal.FindByIdentity(ctx, _settings.AdminGroupName);
        if (group == null)
        {
            return false;
        }

        return user.IsMemberOf(group);
    }
    catch (Exception)
    {
        //This means the username/password combo failed
        return false;
    }
}