ASP.NET MVC로 로그온 시스템을 만들 수 있지만 MembershipProvider를 사용하지 않을 수 있습니까?
사용자 테이블이있는 기존 데이터베이스가 있고 데이터베이스를 가져 와서 ASP.NET MVC로 빌드 된 새 시스템에 사용할 계획입니다. 그러나 내가 불확실한 것은 기존 테이블 구조를 계속 사용할 수 있도록 기본 제공 계정 컨트롤러 또는 일반 멤버십 공급자를 사용하지 않는 로그인 시스템을 만들 수 있는지 여부입니다.
제 질문은 이것이 가능할까요? 아니면 그렇게하기가 특히 어렵습니까?
일을하는 가장 널리 받아 들여지는 방법과 가장 간단한 방법은 무엇입니까?
나는 이와 똑같은 요구 사항을 가졌습니다. 고유 한 사용자 및 역할 스키마가 있고 asp.net 멤버 자격 스키마로 마이그레이션하고 싶지 않았지만 권한 및 역할을 확인하기 위해 ASP.NET MVC 작업 필터를 사용하고 싶었습니다. 정확히 무엇을해야하는지 알아 내기 위해 상당한 양의 파기를해야했지만 결국은 비교적 쉬웠습니다. 나는 당신에게 문제를 해결하고 내가 한 일을 말할 것입니다.
1) System.Web.Security.MembershipProvider에서 파생 된 클래스를 만들었습니다. MembershipProvider에는 암호 분실, 암호 변경, 새 사용자 만들기 등과 같은 모든 종류의 인증 관련 기능에 대한 수많은 추상 메서드가 있습니다. 내가 원했던 것은 내 자신의 스키마에 대해 인증하는 기능뿐이었습니다. 그래서 내 수업에는 주로 빈 재정의가 포함되었습니다. ValidateUser를 덮어 썼습니다.
public override bool ValidateUser(string username, string password)
{
if (string.IsNullOrWhiteSpace(username) ||
string.IsNullOrWhiteSpace(password))
return false;
string hash = EncryptPassword(password);
User user = _repository.GetByUserName(username);
if (user == null) return false;
return user.Password == hash;
}
2) System.Web.Security.RoleProvider에서 파생 된 클래스를 만들었습니다. 다시 말하지만, 역할 생성 및 변경과 같이 필요하지 않은 모든 보풀에 대해 빈 구현이있었습니다. 두 가지 방법을 무시했습니다.
public override string[] GetRolesForUser(string username)
{
User user = _repository.GetByUserName(username);
string[] roles = new string[user.Role.Rights.Count + 1];
roles[0] = user.Role.Description;
int idx = 0;
foreach (Right right in user.Role.Rights)
roles[++idx] = right.Description;
return roles;
}
public override bool IsUserInRole(string username, string roleName)
{
User user = _repository.GetByUserName(username);
if(user!=null)
return user.IsInRole(roleName);
else
return false;
}
3) 그런 다음이 두 클래스를 web.config에 연결했습니다.
<membership defaultProvider="FirstlookMemberProvider" userIsOnlineTimeWindow="15">
<providers>
<clear/>
<add name="FirstlookMemberProvider" type="FirstlookAdmin.DomainEntities.FirstlookMemberProvider, FirstlookAdmin" />
</providers>
</membership>
<roleManager defaultProvider="FirstlookRoleProvider" enabled="true" cacheRolesInCookie="true">
<providers>
<clear/>
<add name="FirstlookRoleProvider" type="FirstlookAdmin.DomainEntities.FirstlookRoleProvider, FirstlookAdmin" />
</providers>
</roleManager>
그게 다야. 기본 권한 부여 작업 필터는 이러한 클래스를 사용합니다. 여전히 로그인 페이지 로그인 및 로그 오프를 처리해야합니다. 평소처럼 표준 양식 인증 클래스를 사용하십시오.
누군가 보안과 관련된 것이 "쉬운"것이라고 말할 때마다 거의 항상 잘못된 것입니다. 비전문가가 놓치기 쉬운 보안에는 많은 미묘함이 있습니다.
In particular, any form of authentication which does not explicitly deal with caching is inherently broken. When an action result is cached, this happens within ASP.NET, not necessarily within the ASP.NET MVC stack. If you examine the source code for AuthorizeAttribute, you will see that it contains some slightly tricky but effective code to ensure that it always runs, even when the action result is cached.
The best way, by far, to customize ASP.NET MVC authentication is to write a custom ASP.NET membership provider. I won't claim that this is foolproof, but there are fewer ways to get in trouble with a broken security implementation in this route then with other methods. A substantial advantage of this technique is that you can substitute a different authorization system at almost any time, with no code changes.
If you must implement a custom MVC attribute, then you should subtype AuthorizeAttribute and override AuthorizeCore, taking careful note of the comments in the source code regarding thread safety.
Of course you can. I did it for my projects completely ignoring the membership provider.
You need to implement your own ActionFilter. Basically, it will intercepts control before a controller action is hit. Inside of it you decide whether to continue on to the action or redirect the user to login page.
For the attribute you can define any parameters you need to support your authentication/authorization model.
public class AuthorizationAttribute : ActionFilterAttribute, IActionFilter
{
public MyRole UserRole { get; set; }
void IActionFilter.OnActionExecuting (ActionExecutedContext filterContext)
{
// Decide whether to grant access to the action or redirect away
}
}
[Authorization (UserRole = MyRole.All)]
public class UserController : Controller
{
[Authorization (UserRole = MyRole.Admin)]
public ActionResult Delete ()
{
}
}
Regarding the concerns expressed in the comments. Yes, enabling output cache will interfere with authorization. One just has to be aware of that.
Explanation of the problem: ASP.NET MVC Tip #40 - Don’t Cache Pages that Require Authorization
You have at least two possibilities
- a custom action filter attribute that will provide your authorization check
- a custom
IHttpModule
that will fill all the necessary data for the logged in user (including roles) and you can use existing action filters
The second choice can be used with regular web forms as well.
'programing tip' 카테고리의 다른 글
자바 스크립트 콜백 범위 (0) | 2020.12.12 |
---|---|
std :: vector.clear ()는 각 요소에서 (사용 가능한 메모리)를 삭제합니까? (0) | 2020.12.12 |
정규식 일치 수 (0) | 2020.12.12 |
파이썬에서 즉시 변수 이름 생성 (0) | 2020.12.12 |
Git을 사용하여 두 가지 브랜치에 커밋 푸시 (0) | 2020.12.12 |