servicestack,Authentication,servicestack" /> servicestack,Authentication,servicestack" />

Authentication 如何使用ServiceStack对web浏览器请求使用基本身份验证?

Authentication 如何使用ServiceStack对web浏览器请求使用基本身份验证?,authentication,servicestack,Authentication,servicestack,我有一个使用ServiceStack构建的RESTAPI。调用REST API时,我正在使用BasicAuthentication,没有任何问题(我正在向BasicAuthProvider注册AuthFeature) 现在我正在尝试构建一些HTML管理页面。这些也应该经过认证 [Authenticate]属性重定向到/login页面,因此我创建了以下DTO和匹配服务来处理登录: [DefaultView("Login")] public class SiteLoginServic

我有一个使用ServiceStack构建的RESTAPI。调用REST API时,我正在使用BasicAuthentication,没有任何问题(我正在向
BasicAuthProvider
注册
AuthFeature

现在我正在尝试构建一些HTML管理页面。这些也应该经过认证

[Authenticate]属性重定向到/login页面,因此我创建了以下DTO和匹配服务来处理登录:

    [DefaultView("Login")]
    public class SiteLoginService : EnshareServiceBase
    {
        public object Get(SiteLoginRequest req)
        {
            return new SiteLoginRequest();
        }

        public object Post(SiteLoginRequest req)
        {
            //I am trying to use the registered IAuthProvider, which is the BasicAuthProvider
            var authProvider = ResolveService<IAuthProvider>();
            authProvider.Authenticate(this, EnshareSession,
                                      new ServiceStack.ServiceInterface.Auth.Auth()
                                      {
                                          Password = req.Password,
                                          UserName = req.UserName
                                      });
            return HttpResult.Redirect(req.Redirect);
        }
    }

    [Route("/login")]
    public class SiteLoginRequest : IReturn<SiteLoginRequest>
    {
        public string Redirect { get; set; }
        public string Password { get; set; }
        public string UserName { get; set; }
    }
[DefaultView(“登录”)]
公共类SiteLoginService:EnshareServiceBase
{
公共对象获取(SiteLoginRequest请求)
{
返回新的SiteLoginRequest();
}
公共对象发布(SiteLoginRequest请求)
{
//我正在尝试使用注册的IAuthProvider,它是BasicAuthProvider
var authProvider=ResolveService();
authProvider.Authenticate(此、EnshareSession、,
新建ServiceStack.ServiceInterface.Auth.Auth()
{
密码=请求密码,
UserName=req.UserName
});
返回HttpResult.Redirect(请求重定向);
}
}
[路由(“/login”)]
公共类SiteLoginRequest:IReturn
{
公共字符串重定向{get;set;}
公共字符串密码{get;set;}
公共字符串用户名{get;set;}
}
但是,当我在登录视图页面上填写用户名和密码并将其发布到SiteLoginService时,BasicAuthProvider总是抛出HttpError:“无效的BasicAuth凭据”。这可能是因为web浏览器没有填写基本身份验证标题,但我不知道如何使用填写的用户名和密码进行身份验证


如何针对使用现有REST API的AuthProvider对站点用户进行正确身份验证?

如果您将用户名和密码作为帖子传递,那么您可能怀疑您没有进行基本身份验证

解释如何使用JavaScript进行基本身份验证。从文章中:

function login() {
    var username = document.getElementById(this.id + "-username").value;
    var password = document.getElementById(this.id + "-password").value;
    this.http.open("get", this.action, false, username, password);
    this.http.send("");
    if (http.status == 200) {
        document.location = this.action;
     } else {
        alert("Incorrect username and/or password.");
    }
    return false;
}

ServiceStack还支持其他形式的身份验证,包括根据需要通过POST发送用户名和密码。如果您解释您的要求,我们可以提供一些建议。

我想我还需要在AuthFeature中包含CredentialAuthProvider,它将公开/auth/credentials服务,我将表单发布到该服务

        //this inherits the BasicAuthProvider and is used to authenticate the REST API calls
        var myCustomAuthProvider = new CustomAuthProvider(appSettings);
        var credentialsProvider = new CredentialsAuthProvider(appSettings);
        container.Register<IAuthProvider>(myCustomAuthProvider);
        container.Register<CredentialsAuthProvider>(credentialsProvider);
        var authFeature = new AuthFeature(() => new EnshareSession(new MongoTenantRepository()),
                                          new IAuthProvider[] {
                                                                  myCustomAuthProvider,
                                                                  credentialsProvider 
                                                               })
它正在设置会话cookie(X-AUId),并且用户已正确验证。对使用Authenticate属性修饰的服务的后续web浏览器请求成功

因此,唯一缺少的部分是如何确保用户在发布到
/auth/credentials
后正确重定向

为了确保重定向有效,快速查看已显示需要一个Continue参数

这就是登录表单的外观(我在模型中重用了ServiceStack中的Auth类):

@继承ViewPage
@{
Layout=“AdminLayout”;
}

@LabelFor(m=>m.UserName,“登录名:”) @Html.TextBoxFor(u=>u.UserName)

@LabelFor(m=>m.Password) @Html.PasswordFor(m=>m.Password)

@Html.HiddenFor(m=>m.Continue)

Continue属性从其模型的Redirect属性填充到服务中。

我不想使用javascript进行身份验证。我想从html表单执行一个普通的http post。注册AuthFeature时是否包含了
新的BasicAuthProvider()
?最初,我只包含从BasicAuthProvider继承的CustomAuthProvider。解决方案是还包括CredentialAuthProvider——我在下面发布了自己的答案。
        <form action="/auth/credentials" method="post">
            <p class="entryfield">
                @Html.LabelFor(m => m.UserName, "Login name:")
                @Html.TextBoxFor(u => u.UserName)
            </p>
            <p class="entryfield">
                @Html.LabelFor(m => m.Password)
                @Html.PasswordFor(m => m.Password)
            </p>
            <input class="formbutton" type="submit" value="Login" />
        </form>
    HTTP/1.1 302 Found
    Server: ASP.NET Development Server/10.0.0.0
    Date: Wed, 30 Oct 2013 08:15:54 GMT
    X-AspNet-Version: 4.0.30319
    X-Powered-By: ServiceStack/3,969 Win32NT/.NET
    Location: http://localhost:64944/login?redirect=%2fadmin
    Set-Cookie: X-UAId=3; expires=Sun, 30-Oct-2033 08:15:54 GMT; path=/; HttpOnly
    @inherits ViewPage<ServiceStack.ServiceInterface.Auth.Auth>
    @{

        Layout = "AdminLayout";
    }

    <form action="/auth/credentials" method="post">
        <p class="entryfield">
            @Html.LabelFor(m => m.UserName, "Login name:")
            @Html.TextBoxFor(u => u.UserName)
        </p>
        <p class="entryfield">
            @Html.LabelFor(m => m.Password)
            @Html.PasswordFor(m => m.Password)
        </p>
        @Html.HiddenFor(m => m.Continue)
        <input type="submit" value="Login" />
    </form>