我想简单的身份验证和授权添加到ASP.NET MVC应用程序。
我只是想对一些附加的功能钉基本窗体身份验证(由于简单性和自定义数据库结构)
假设这是我的数据库结构:用户名:(。理想的一些枚举字符串如果需要的话目前,用户只有一个角色,但是这可能会改变)用户名密码角色
高层次的问题:鉴于上述数据库结构,我想能够做到以下几点:
- 使用窗体身份验证简单登录
- 装饰我的行动与:[授权(角色= {MyRoles.Admin,MyRoles.Member})]
- 使用角色在我的意见(以确定链接在一些谐音显示)
目前,所有我真的很肯定的是如何进行身份验证。 之后,我迷路了。 我不知道在这一点我抢用户角色(登录,每个授权?)。 由于我的角色可能不字符串,我不知道他们会如何适应与User.IsInRole()。
现在,我问这里是因为我还没有找到一个“简单”的完成我需要什么。 我已经看到了多个例子。
对于身份验证:
- 我们有检查数据库和“SetAuthCookie”简单的用户验证
- 或者,我们重写成员供应商,这样做的ValidateUser内部在这两种,我不知道如何在我的简单的用户粘性的角色,让他们一起工作的:HttpContext.Current.User.IsInRole(“管理员”)此外,我不知道如何修改这个与我的枚举值工作。
对于授权,我已经看到了:
- 推导AuthorizeAttribute和实施AuthorizeCore OR OnAuthorization来处理角色?
- 实现IPrincipal的?
任何援助将不胜感激。 不过,我担心我可能需要很多的细节,因为没有什么我GOOGLE似乎适合什么我需要做的。
建立一个自定义AuthorizeAttribute
,可以使用您的枚举,而不是字符串。 当你需要授权,转换枚举为字符串通过附加枚举类型名称+枚举值,并使用IsInRole
从那里。
要添加到角色,你需要连接到一个授权用户HttpApplication
AuthenticateRequest
事件像在第一代码http://www.eggheadcafe.com/articles/20020906.asp (但如果报表到保护条款反转大量嵌套!) 。
您可以往返的用户角色的窗体身份验证Cookie或从数据库中每一次抓住他们。
我想我已经实现类似的东西。
我的解决方案的基础上的NerdDinner 教程 ,是继。
当您登录用户 ,添加如下代码:
var authTicket = new FormsAuthenticationTicket(
1, // version
userName, // user name
DateTime.Now, // created
DateTime.Now.AddMinutes(20), // expires
rememberMe, // persistent?
"Moderator;Admin" // can be used to store roles
);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
HttpContext.Current.Response.Cookies.Add(authCookie);
添加以下代码Global.asax.cs
:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null || authCookie.Value == "")
return;
FormsAuthenticationTicket authTicket;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch
{
return;
}
// retrieve roles from UserData
string[] roles = authTicket.UserData.Split(';');
if (Context.User != null)
Context.User = new GenericPrincipal(Context.User.Identity, roles);
}
你这样做之后,你可以使用[Authorize]
在你的控制器动作代码属性:
[Authorize(Roles="Admin")]
public ActionResult AdminIndex ()
请让我知道,如果您还有其他问题。
我做了这样的事情:
- 使用Global.asax.cs中加载要在会议上,缓存或应用程序状态比较角色,或加载它们对的ValidateUser控制器上飞
在[授权]属性分配给你的控制器,你想要求授权
[Authorize(Roles = "Admin,Tech")]
或允许访问,例如登录和的ValidateUser控制器使用以下属性
[AllowAnonymous]
我的登录表单
<form id="formLogin" name="formLogin" method="post" action="ValidateUser">
<table>
<tr>
<td>
<label for="txtUserName">Username: (AD username) </label>
</td>
<td>
<input id="txtUserName" name="txtUserName" role="textbox" type="text" />
</td>
</tr>
<tr>
<td>
<label for="txtPassword">Password: </label>
</td>
<td>
<input id="txtPassword" name="txtPassword" role="textbox" type="password" />
</td>
</tr>
<tr>
<td>
<p>
<input id="btnLogin" type="submit" value="LogIn" class="formbutton" />
</p>
</td>
</tr>
</table>
@Html.Raw("<span id='lblLoginError'>" + @errMessage + "</span>")
</form>
登录控制器和控制器的ValidateUser从窗体调用后
验证用户通过该验证对Windows的AD语境本地服务WCF服务的身份验证,但你可以改变这个你自己的身份验证机制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Security.Principal;
using MyMVCProject.Extensions;
namespace MyMVCProject.Controllers
{
public class SecurityController : Controller
{
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
Session["LoginReturnURL"] = returnUrl;
Session["PageName"] = "Login";
return View("Login");
}
[AllowAnonymous]
public ActionResult ValidateUser()
{
Session["PageName"] = "Login";
ViewResult retVal = null;
string loginError = string.Empty;
HttpContext.User = null;
var adClient = HttpContext.Application.GetApplicationStateWCFServiceProxyBase.ServiceProxyBase<UserOperationsReference.IUserOperations>>("ADService").Channel;
var username = Request.Form["txtUserName"];
var password = Request.Form["txtPassword"];
//check for ad domain name prefix
if (username.Contains(@"\"))
username = username.Split('\\')[1];
//check for the existence of the account
var acctReq = new UserOperationsReference.DoesAccountExistRequest();
acctReq.userName = username;
//account existence result
var accountExist = adClient.DoesAccountExist(acctReq);
if (!accountExist.DoesAccountExistResult)
{
//no account; inform the user
return View("Login", new object[] { "NO_ACCOUNT", accountExist.errorMessage });
}
//authenticate
var authReq = new UserOperationsReference.AuthenticateRequest();
authReq.userName = username;
authReq.passWord = password;
var authResponse = adClient.Authenticate(authReq);
String verifiedRoles = string.Empty;
//check to make sure the login was as success against the ad service endpoint
if (authResponse.AuthenticateResult == UserOperationsReference.DirectoryServicesEnumsUserProperties.SUCCESS)
{
Dictionary<string, string[]> siteRoles = null;
//get the role types and roles
if (HttpContext.Application["UISiteRoles"] != null)
siteRoles = HttpContext.Application.GetApplicationState<Dictionary<string, string[]>>("UISiteRoles");
string groupResponseError = string.Empty;
if (siteRoles != null && siteRoles.Count > 0)
{
//get the user roles from the AD service
var groupsReq = new UserOperationsReference.GetUsersGroupsRequest();
groupsReq.userName = username;
//execute the service method for getting the roles/groups
var groupsResponse = adClient.GetUsersGroups(groupsReq);
//retrieve the results
if (groupsResponse != null)
{
groupResponseError = groupsResponse.errorMessage;
var adRoles = groupsResponse.GetUsersGroupsResult;
if (adRoles != null)
{
//loop through the roles returned from the server
foreach (var adRole in adRoles)
{
//look for an admin role first
foreach (var roleName in siteRoles.Keys)
{
var roles = siteRoles[roleName].ToList();
foreach (var role in roles)
{
if (adRole.Equals(role, StringComparison.InvariantCultureIgnoreCase))
{
//we found a role, stop looking
verifiedRoles += roleName + ";";
break;
}
}
}
}
}
}
}
if (String.IsNullOrEmpty(verifiedRoles))
{
//no valid role we need to inform the user
return View("Login", new object[] { "NO_ACCESS_ROLE", groupResponseError });
}
if (verifiedRoles.EndsWith(";"))
verifiedRoles = verifiedRoles.Remove(verifiedRoles.Length - 1, 1);
//all is authenticated not build the auth ticket
var authTicket = new FormsAuthenticationTicket(
1, // version
username, // user name
DateTime.Now, // created
DateTime.Now.AddMinutes(20), // expires
true, // persistent?
verifiedRoles // can be used to store roles
);
//encrypt the ticket before adding it to the http response
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
Response.Cookies.Add(authCookie);
Session["UserRoles"] = verifiedRoles.Split(';');
//redirect to calling page
Response.Redirect(Session["LoginReturnURL"].ToString());
}
else
{
retVal = View("Login", new object[] { authResponse.AuthenticateResult.ToString(), authResponse.errorMessage });
}
return retVal;
}
}
}
现在用户进行身份验证创建新标识
protected void FormsAuthentication_OnAuthenticate(Object sender, FormsAuthenticationEventArgs e)
{
if (FormsAuthentication.CookiesSupported == true)
{
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null || authCookie.Value == "")
return;
FormsAuthenticationTicket authTicket = null;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch
{
return;
}
// retrieve roles from UserData
if (authTicket.UserData == null)
return;
//get username from ticket
string username = authTicket.Name;
Context.User = new GenericPrincipal(
new System.Security.Principal.GenericIdentity(username, "MyCustomAuthTypeName"), authTicket.UserData.Split(';'));
}
}
在我的网站在我_Layout.cshtml的顶部我有这样的事情
{
bool authedUser = false;
if (User != null && User.Identity.AuthenticationType == "MyCustomAuthTypeName" && User.Identity.IsAuthenticated)
{
authedUser = true;
}
}
然后在体内
@{
if (authedUser)
{
<span id="loggedIn_userName">
<label>User Logged In: </label>@User.Identity.Name.ToUpper()
</span>
}
else
{
<span id="loggedIn_userName_none">
<label>No User Logged In</label>
</span>
}
}
将用户添加到表“中的角色的用户”。 使用存储过程“addusertorole”(类似的东西)在你的代码添加到各种角色。 您可以在“角色”表很简单地创建的角色。
你的表使用:用户,UsersInRole,角色
使用内置的存储的特效来处理这些表。 然后,所有你需要做的就是添加属性。
例如,你可以对选择用户,并将它们添加到一个角色上的视图的“管理”属性。 您可以使用存储过程将该用户添加到角色。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using SISWEBBSI.Models.Model;
using SISWEBBSI.Models.Model.Entities;
using SISWEBBSI.Models.ViewModel;
namespace SISWEBBSI.Controllers.ActionFilter
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public sealed class RequerAutorizacao : ActionFilterAttribute
{
public Grupo.Papeis[] Papeis = {} ;
public string ViewName { get; set; }
public ViewDataDictionary ViewDataDictionary { get; set; }
public AcessoNegadoViewModel AcessoNegadoViewModel { get; set; }
public override void OnActionExecuting(ActionExecutingContext FilterContext)
{
if (!FilterContext.HttpContext.User.Identity.IsAuthenticated)
{
string UrlSucesso = FilterContext.HttpContext.Request.Url.AbsolutePath;
string UrlRedirecionar = string.Format("?ReturnUrl={0}", UrlSucesso);
string UrlLogin = FormsAuthentication.LoginUrl + UrlRedirecionar;
FilterContext.HttpContext.Response.Redirect(UrlLogin, true);
}
else
{
if (Papeis.Length > 0)
{
//Papel ADMINISTRADOR sempre terá acesso quando alguma restrição de papeis for colocada.
int NovoTamanho = Papeis.Count() + 1;
Array.Resize(ref Papeis, NovoTamanho);
Papeis[NovoTamanho - 1] = Grupo.Papeis.ADMINISTRADOR;
UsuarioModel Model = new UsuarioModel();
if (!Model.UsuarioExecutaPapel(FilterContext.HttpContext.User.Identity.Name, Papeis))
{
ViewName = "AcessoNegado";
String Mensagem = "Você não possui privilégios suficientes para essa operação. Você deve estar nos grupos que possuem";
if(Papeis.Length == 1)
{
Mensagem = Mensagem + " o papel: <BR/>";
}
else if (Papeis.Length > 1)
{
Mensagem = Mensagem + " os papéis: <BR/>";
}
foreach (var papel in Papeis)
{
Mensagem = Mensagem + papel.ToString() + "<br/>";
}
AcessoNegadoViewModel = new AcessoNegadoViewModel();
AcessoNegadoViewModel.Mensagem = Mensagem;
ViewDataDictionary = new ViewDataDictionary(AcessoNegadoViewModel);
FilterContext.Result = new ViewResult { ViewName = ViewName, ViewData = ViewDataDictionary };
return;
}
}
}
}
}
}