programing tip

암호 재설정 토큰 생성이 Azure 웹 사이트에서 작동하지 않습니다.

itbloger 2020. 12. 10. 19:08
반응형

암호 재설정 토큰 생성이 Azure 웹 사이트에서 작동하지 않습니다.


UserManagerASP.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();

    // ...
}

참고URL : https://stackoverflow.com/questions/23455579/generating-reset-password-token-does-not-work-in-azure-website

반응형