Я пытаюсь создать сервер веб-API с аутентификацией, используя Owin и связанные с ним вещи. Проблема в том, что мой разработчик внешнего интерфейса отправит в виде JSON текст сообщения электронной почты и пароль для проверки подлинности. Пожалуйста, помогите мне, где я не прав, сообщение всегда
{
"Message": "Authorization has been denied for this request."
}
Вот мой запрос на вход в LoginController.cs
[HttpPost]
[Authorize]
[Route("token/reg/signin")]
public async Task<HttpResponseMessage> SubmitSignIn([FromBody]object data)
{
//Convert data receive to json string
string json = JsonConvert.SerializeObject(data);
Debug.WriteLine("Receive value:" + json);
//Initial user registration info and convert json string to class
DefStruct.LoginInfo logInfo = new DefStruct.LoginInfo();
logInfo = JsonConvert.DeserializeObject<DefStruct.LoginInfo>(json);
//Check the connection state with DB
if (SQLConnection.Instance.Conn.State != ConnectionState.Open)
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, DefString.DATABASE_ERROR);
//Check user register email available or not
bool isAvailable = await RegQuery.CheckEmail(logInfo.Email);
if (isAvailable)
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, DefString.EMAIL_NOT_EXIST);
//Check email and password is validate or not
bool isValidate = await RegQuery.ValidateUser(logInfo.Email, logInfo.Password);
if (!isValidate)
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, DefString.WRONG_EMAIL_PASSWORD);
return Request.CreateResponse(HttpStatusCode.OK, "Login sucess");
}
Вот мой Startup.cs
public class Startup
{
public static Startup Instance { get; private set; }
public OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }
public void ConfigureAuth(IAppBuilder app)
{
OAuthOptions = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
Provider = new ApplicationAuthorizationProvider()
};
OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
app.UseOAuthBearerTokens(OAuthOptions);
app.UseOAuthAuthorizationServer(OAuthOptions);
app.UseOAuthBearerAuthentication(OAuthBearerOptions);
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseWebApi(config);
}
public void Configuration(IAppBuilder app)
{
//Default configuration
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
//Custom configuration
DataSourceConfig.ConnectDatabase();
ModulesConfig.InitialAllModules();
//Authentication configuration
ConfigureAuth(app);
Instance = this;
}
public string GetToken(AuthenticationTicket ticketData)
{
string token;
token = OAuthBearerOptions.AccessTokenFormat.Protect(ticketData);
return token;
}
}
Вот ApplicationAuthorizationProvider.cs
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
//Read the position to the end
context.Request.Body.Position = 0;
//Convert to json string
var payload = await new StreamReader(context.Request.Body).ReadToEndAsync();
//Parse json string
DefStruct.LoginInfo logInfo = JsonConvert.DeserializeObject<DefStruct.LoginInfo>(payload);
context.OwinContext.Set<string>("email", logInfo.Email);
context.OwinContext.Set<string>("password", logInfo.Password);
context.Validated();
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var email = context.OwinContext.Get<string>("email");
var password = context.OwinContext.Get<string>("password");
var user = await RegQuery.ValidateUser(email, password);
if(user)
{
var claim = new Claim(ClaimTypes.Email, email);
var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
oAuthIdentity.AddClaim(claim);
var properties = Authentication.CreateProperties(email);
var ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
}
else
{
context.SetError("invalid_grant", "The email or password is incorrect.");
}
}
Есть 3 вещи, которые я до сих пор путаю:
Почему запрос token/reg/signin
никогда не запускается ValidateClientAuthentication и GrantResourceOwnerCredentials ? Кто-нибудь может объяснить причину?
Если я хочу создать токен вручную, я вызывал этот код из своего класса Authentication.cs , который GetToken inside Startup.cs и accessToken
всегда возвращают ноль. Почему?
public static string GenerateToken(string email)
{
string accessToken;
var claim = new Claim(ClaimTypes.Email, email);
var oAuthIdentity = new ClaimsIdentity();
oAuthIdentity.AddClaim(claim);
var properties = CreateProperties(email);
var ticket = new AuthenticationTicket(oAuthIdentity, properties);
accessToken = Startup.Instance.GetToken(ticket);
return accessToken;
}
public static AuthenticationProperties CreateProperties(string email)
{
IDictionary<string, string> data = new Dictionary<string, string>
{
{ "email", email }
};
return new AuthenticationProperties(data);
}
Так что вообще не так, мои идеи просты: клиент отправляет запрос в виде JSON -> сервер читает -> проверен -> генерирует токен и отправляет ответ с дополнительным ответом на данные, но это уже занимает несколько дней с огромным поиском в Google,Может быть, мой вопрос настолько глуп, что кто-то уже сделал это, но, пожалуйста, помогите мне разобраться