将基本 HTTP 身份验证添加到 WCF REST 服务

编程入门 行业动态 更新时间:2024-10-28 12:30:06
本文介绍了将基本 HTTP 身份验证添加到 WCF REST 服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个 WCF HTTP REST 服务,我将它与使用不同编程语言的 HTTP 客户端联系起来,该客户端编写自己的自定义 HTTP.我想为我的 WCF 服务添加 WWW-Authenticate 基本身份验证支持.

I have a WCF HTTP REST Service and I tie into it with an HTTP client in a different programming language who writes its own custom HTTP. I would like to add WWW-Authenticate basic authentication support to my WCF service.

我的方法是这样的:

[WebInvoke(UriTemplate = "widgets", Method = "POST")] public XElement CreateWidget(XElement e) { ... }

我是否可以以某种方式过滤传入的 HTTP 请求,以便我可以在访问上述 CreateWidget 等每个 REST 方法之前检查有效的 Basic auth 字符串?注意:我的身份验证信息存储在我的数据库中.

Is it possible for me to somehow filter incoming HTTP requests so I can check for a valid Basic auth string before it hits each of the REST methods like CreateWidget above? Note: My auth info is stord in my database.

基本上我想在请求标头中检查这个:授权:基本 QWxhZGRpbjpvcGVuIHNlc2FtZQ== 然后我可以自己解析该字符串并验证数据库中的 u/p.

Basically I want to check for this in the request headers: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== and then I can myself parse that string and validate the u/p in the database.

web.config文件如下:

The web.config file is as follows:

<?xml version="1.0"?> <configuration> <connectionStrings> <add name="DatabaseConnectionString" connectionString="Data Source=.SQLEXPRESS;Initial Catalog=Database;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <compilation debug="true" targetFramework="4.0" /> <httpRuntime maxRequestLength="10485760" /> </system.web> <system.webServer> <modules runAllManagedModulesForAllRequests="true"> <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> </modules> </system.webServer> <system.serviceModel> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> <standardEndpoints> <webHttpEndpoint> <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" maxReceivedMessageSize="1048576" maxBufferSize="1048576" /> </webHttpEndpoint> </standardEndpoints> </system.serviceModel> </configuration>

推荐答案

我也对 REST HTTP WCF 服务中的自定义身份验证感兴趣,并最终将其投入使用.

I was also interested in custom authentication in a REST HTTP WCF service and finally got it to work.

话虽如此,我的代码将为您提供一种使其工作的方法,但我建议您阅读本指南,其中更深入地解释了所有内容:wcfsecurityguide.codeplex/

That being said my code will give you a way to get it working, but I recommend reading this guide which explains everything in more depth: wcfsecurityguide.codeplex/

首先,将 Web.Config 的 system.web 部分更改为如下所示:

First, change the system.web portion of your Web.Config to look like this:

<system.web> <compilation debug="true" targetFramework="4.0" /> <httpRuntime maxRequestLength="10485760" /> <authentication mode="None"></authentication> <httpModules> <add name="BasicAuthenticationModule" type="YourNamespace.UserNameAuthenticator" /> </httpModules> </system.web>

然后将另一个文件添加到您的项目中:UserNameAuthenticator.cs

Then add another file to your project: UserNameAuthenticator.cs

using System; using System.Collections.Generic; using System.Text; using System.Web; using System.Web.Security; using System.Security.Principal; using System.ServiceModel.Activation; namespace YourNamespace { public class UserNameAuthenticator : IHttpModule { public void Dispose() { } public void Init(HttpApplication application) { application.AuthenticateRequest += new EventHandler(this.OnAuthenticateRequest); application.AuthorizeRequest += new EventHandler(this.OnAuthorizationRequest); application.EndRequest += new EventHandler(this.OnEndRequest); } public bool CustomAuth(string username, string password) { //TODO: Implement your custom auth logic here return true; } public string[] GetCustomRoles(string username) { return new string[] { "read", "write" }; } public void OnAuthorizationRequest(object source, EventArgs eventArgs) { HttpApplication app = (HttpApplication)source; //If you want to handle authorization differently from authentication } public void OnAuthenticateRequest(object source, EventArgs eventArgs) { HttpApplication app = (HttpApplication)source; //the Authorization header is checked if present string authHeader = app.Request.Headers["Authorization"]; if (!string.IsNullOrEmpty(authHeader)) { string authStr = app.Request.Headers["Authorization"]; if (authStr == null || authStr.Length == 0) { // No credentials; anonymous request return; } authStr = authStr.Trim(); if (authStr.IndexOf("Basic", 0) != 0) { //header not correct we do not authenticate return; } authStr = authStr.Trim(); string encodedCredentials = authStr.Substring(6); byte[] decodedBytes = Convert.FromBase64String(encodedCredentials); string s = new ASCIIEncoding().GetString(decodedBytes); string[] userPass = s.Split(new char[] { ':' }); string username = userPass[0]; string password = userPass[1]; //the user is validated against the SqlMemberShipProvider //If it is validated then the roles are retrieved from the //role provider and a generic principal is created //the generic principal is assigned to the user context // of the application if (CustomAuth(username, password)) { string[] roles = GetCustomRoles(username); app.Context.User = new GenericPrincipal(new GenericIdentity(username, "Membership Provider"), roles); } else { DenyAccess(app); return; } } else { //the authorization header is not present //the status of response is set to 401 and it ended //the end request will check if it is 401 and add //the authentication header so the client knows //it needs to send credentials to authenticate app.Response.StatusCode = 401; app.Response.End(); } } public void OnEndRequest(object source, EventArgs eventArgs) { if (HttpContext.Current.Response.StatusCode == 401) { //if the status is 401 the WWW-Authenticated is added to //the response so client knows it needs to send credentials HttpContext context = HttpContext.Current; context.Response.StatusCode = 401; context.Response.AddHeader("WWW-Authenticate", "Basic Realm"); } } private void DenyAccess(HttpApplication app) { app.Response.StatusCode = 401; app.Response.StatusDescription = "Access Denied"; // error not authenticated app.Response.Write("401 Access Denied"); app.CompleteRequest(); } } // End Class } //End Namespace

更多推荐

将基本 HTTP 身份验证添加到 WCF REST 服务

本文发布于:2023-11-14 05:05:21,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1586299.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:身份验证   HTTP   REST   WCF

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!