암호 재설정 토큰 생성이 Azure 웹 사이트에서 작동하지 않습니다.
UserManager
ASP.NET 5와 함께 제공되는 기본 클래스를 사용하여 내 사이트에서 암호 재설정 기능을 구현하고 있습니다 .
내 개발 환경에서 모든 것이 잘 작동합니다. 그러나 Azure 웹 사이트로 실행되는 프로덕션 사이트에서 시도하면 다음 예외가 발생합니다.
System.Security.Cryptography.CryptographicException : 데이터 보호 작업이 실패했습니다. 이는 현재 스레드의 사용자 컨텍스트에 대한 사용자 프로필이로드되지 않았기 때문에 발생했을 수 있습니다. 스레드가 가장하는 경우 일 수 있습니다.
이것이 내가 UserManager
인스턴스를 설정하는 방법입니다 .
var provider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider(SiteConfig.SiteName);
UserManager.UserTokenProvider = new Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider<User>(provider.Create(ResetPasswordPurpose));
그런 다음 토큰을 생성합니다 (사용자가 실제로 암호를 재설정 할 것인지 확인할 수 있도록 사용자에게 이메일로 전송 됨).
string token = UserManager.GeneratePasswordResetToken(user.Id);
불행히도 이것이 Azure에서 실행될 때 위의 예외가 발생합니다.
나는 주변을 검색했고이 가능한 해결책을 찾았다 . 그러나 전혀 작동하지 않았고 여전히 동일한 예외가 발생합니다.
링크에 따르면 Azure와 같은 웹 팜에서 작동하지 않는 세션 토큰과 관련이 있습니다.
DpapiDataProtectionProvider는 암호화 된 데이터를 암호화 한 시스템에서만 해독 할 수 있기 때문에 웹 팜 / 클라우드 환경에서 제대로 작동하지 않는 DPAPI 를 사용 합니다. 필요한 것은 사용자 환경의 모든 컴퓨터에서 해독 할 수 있도록 데이터를 암호화하는 방법입니다. 불행히도 ASP.NET Identity 2.0에는 DpapiDataProtectionProvider 이외의 다른 IProtectionProvider 구현이 포함되어 있지 않습니다. 그러나 직접 굴리는 것은 그리 어렵지 않습니다.
한 가지 옵션은 MachineKey 클래스 를 다음과 같이 활용 하는 것입니다.
public class MachineKeyProtectionProvider : IDataProtectionProvider
{
public IDataProtector Create(params string[] purposes)
{
return new MachineKeyDataProtector(purposes);
}
}
public class MachineKeyDataProtector : IDataProtector
{
private readonly string[] _purposes;
public MachineKeyDataProtector(string[] purposes)
{
_purposes = purposes;
}
public byte[] Protect(byte[] userData)
{
return MachineKey.Protect(userData, _purposes);
}
public byte[] Unprotect(byte[] protectedData)
{
return MachineKey.Unprotect(protectedData, _purposes);
}
}
이 옵션을 사용하려면 따라야 할 몇 가지 단계가 있습니다.
1 단계
MachineKeyProtectionProvider를 사용하도록 코드를 수정합니다.
using Microsoft.AspNet.Identity.Owin;
// ...
var provider = new MachineKeyProtectionProvider();
UserManager.UserTokenProvider = new DataProtectorTokenProvider<User>(
provider.Create("ResetPasswordPurpose"));
2 단계
웹 팜 / 클라우드 환경의 모든 컴퓨터에서 MachineKey 값을 동기화 합니다. 무섭게 들리지만 웹 팜에서 ViewState 유효성 검사가 제대로 작동하도록하기 위해 이전에 여러 번 수행 한 것과 동일한 단계입니다 (DPAPI도 사용함).
사용을 고려 IAppBuilder.GetDataProtectionProvider()
하는 대신 새로운 선언 DpapiDataProtectionProvider
.
여러분과 마찬가지로 제가 찾은 코드 샘플에서 다음과 같이 UserManager를 구성하여이 문제를 소개했습니다.
public class UserManager : UserManager<ApplicationUser>
{
public UserManager() : base(new UserStore<ApplicationUser>(new MyDbContext()))
{
// this does not work on azure!!!
var provider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("ASP.NET IDENTITY");
this.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(provider.Create("EmailConfirmation"))
{
TokenLifespan = TimeSpan.FromHours(24),
};
}
}
The CodePlex issue linked to above actually references a blog post which has been updated with a simpler solution to the problem. It recommends saving a static reference to the IDataProtector
...
public partial class Startup
{
internal static IDataProtectionProvider DataProtectionProvider { get; private set; }
public void ConfigureAuth(IAppBuilder app)
{
DataProtectionProvider = app.GetDataProtectionProvider();
// other stuff.
}
}
...and then referencing it from within the UserManager
public class UserManager : UserManager<ApplicationUser>
{
public UserManager() : base(new UserStore<ApplicationUser>(new MyDbContext()))
{
var dataProtectionProvider = Startup.DataProtectionProvider;
this.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
// do other configuration
}
}
The answer from johnso also provides a good example of how to wire this up using Autofac.
I had the same issues except I was hosting on amazon ec2.
I was able to resolve it by going to the application pool in IIS and (under advanced settings after a right click) setting process model - load user profile = true.
I was having the same issue (Owin.Security.DataProtection.DpapiDataProtectionProvider
failing when ran on Azure), and Staley is correct, you cannot use DpapiDataProtectionProvider
.
If you're using OWIN Startup Classes you can avoid rolling your own IDataProtectionProvider
, instead use the GetDataProtectionProvider
method of IAppBuilder
.
For instance, with Autofac:
internal static IDataProtectionProvider DataProtectionProvider;
public void ConfigureAuth(IAppBuilder app)
{
// ...
DataProtectionProvider = app.GetDataProtectionProvider();
builder.Register<IDataProtectionProvider>(c => DataProtectionProvider)
.InstancePerLifetimeScope();
// ...
}
'programing tip' 카테고리의 다른 글
Java에서 ResultSet이 리턴 한 행 수 가져 오기 (0) | 2020.12.10 |
---|---|
Mac OS X에 pdftk를 설치하는 방법 (0) | 2020.12.10 |
2 개의 날짜를 빼기위한 LINQ to Entities (0) | 2020.12.10 |
비정규 화는 어떤 방식으로 데이터베이스 성능을 향상합니까? (0) | 2020.12.10 |
Emacs : 버퍼를 지우는 단축키는 무엇입니까? (0) | 2020.12.10 |