ASP.NET 웹 API의 사용자 인증


150

이 주제는 매우 혼란 스러웠습니다. 나는 HTTP 응용 프로그램의 신인이지만 어딘가에서 JSON 데이터를 사용하는 iPhone 클라이언트를 개발해야합니다. MS에서 Web API를 선택하는 것은 쉬운 것처럼 보였지만 사용자 인증과 관련하여 상당히 실망 스럽습니다.

몇 시간의 인터넷 검색 후 로그인 화면에서 사용자 Authorize속성 을 사용하는 ApiController방법에 이르기까지 사용자를 인증하는 방법에 대한 명확한 예를 찾을 수 없었던 방법에 놀랐습니다 .

이것은 질문이 아니라 이것을 정확히 수행하는 방법에 대한 예입니다. 다음 페이지를 살펴 보았습니다.

이들은 승인되지 않은 요청을 처리하는 방법을 설명하지만 LoginController사용자 자격 증명을 요청하고 유효성을 검사하는 것과 같은 것을 명확하게 보여주지는 않습니다 .

좋은 간단한 예를 쓰거나 올바른 방향으로 나를 가리켜 줄 사람이 있습니까?

감사.


1
나는 이것에 대해 같은 질문에 대답했다 : stackoverflow.com/questions/11775594/…
cuongle

asp.net이 포함 된 Web Api의 경우 mvc 앱에서와 같이 쿠키 및 양식 인증 모듈 만 사용할 수 있습니다 (원하는 경우). 따라서 웹 API 코드에서 사용자가 로그인했는지 확인하기 위해 주체를 확인할 수 있습니다 (예 : 이전과 동일).
Elliot


많은 사람들이 asp.net/web-api/overview/security/… 기사를 읽는 것이 좋습니다 .
영재

답변:


176

몇 시간의 인터넷 검색 후 로그인 화면에서 ApiController 메소드의 Authorize 속성을 사용하여 사용자 권한을 인증하는 방법에 대한 명확한 예를 찾지 못한 방법에 놀랐습니다.

이 두 가지 개념에 대해 혼란스러워하기 때문입니다.

  • 인증은 시스템이 사용자를 안전하게 식별 할 수있는 메커니즘입니다. 인증 시스템은 다음과 같은 질문에 대한 답변을 제공합니다.

    • 사용자는 누구입니까?
    • 사용자는 실제로 자신을 대표하는 사람입니까?
  • 권한 부여는 시스템이 특정 인증 된 사용자가 시스템에서 제어하는 ​​보안 리소스에 대해 어느 수준의 액세스 권한을 가져야하는지 결정하는 메커니즘입니다. 예를 들어, 데이터베이스 관리 시스템은 특정 개인에게 데이터베이스에서 정보를 검색 할 수 있지만 데이터베이스에 저장된 데이터를 변경하는 기능은 제공하지 않고 다른 개인에게는 데이터를 변경하는 기능을 제공하도록 설계 될 수 있습니다. 인증 시스템은 다음과 같은 질문에 대한 답변을 제공합니다.

    • 사용자 X는 자원 R에 액세스 할 권한이 있습니까?
    • 사용자 X에게 P 작업을 수행 할 권한이 있습니까?
    • 사용자 X는 자원 R에 대해 P 작업을 수행 할 권한이 있습니까?

AuthorizeMVC 의 속성은 다음과 같은 액세스 규칙을 적용하는 데 사용됩니다.

 [System.Web.Http.Authorize(Roles = "Admin, Super User")]
 public ActionResult AdministratorsOnly()
 {
     return View();
 }

위 규칙 에 따라 관리자수퍼 유저 역할의 사용자메소드에 액세스 할 수 있습니다

이 규칙은 location요소를 사용하여 web.config 파일에서 설정할 수도 있습니다 . 예:

  <location path="Home/AdministratorsOnly">
    <system.web>
      <authorization>
        <allow roles="Administrators"/>
        <deny users="*"/>
      </authorization>
    </system.web>
  </location>

그러나 이러한 권한 부여 규칙을 실행하기 전에 현재 웹 사이트에 대한 인증을 받아야 합니다 .

이것들은 무단 요청을 처리하는 방법을 설명하지만 LoginController와 같은 것을 보여 주거나 사용자 자격 증명을 요청하고 유효성을 검사하는 것과 같은 것을 분명히 보여주지는 않습니다.

여기에서 문제를 두 가지로 나눌 수 있습니다.

  • 동일한 웹 애플리케이션에서 웹 API 서비스를 사용할 때 사용자를 인증하십시오.

    ASP.Net인증에 의존하기 때문에 가장 간단한 방법입니다.

    이것은 간단한 예입니다.

    Web.config

    <authentication mode="Forms">
      <forms
        protection="All"
        slidingExpiration="true"
        loginUrl="account/login"
        cookieless="UseCookies"
        enableCrossAppRedirects="false"
        name="cookieName"
      />
    </authentication>

    사용자는 계정 / 로그인 경로 로 리디렉션되며 사용자 자격 증명을 요청하는 사용자 지정 컨트롤을 렌더링 한 후 다음을 사용하여 인증 쿠키를 설정합니다.

        if (ModelState.IsValid)
        {
            if (Membership.ValidateUser(model.UserName, model.Password))
            {
                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                return RedirectToAction("Index", "Home");
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }
        }
    
        // If we got this far, something failed, redisplay form
        return View(model);
  • 크로스 플랫폼 인증

    이 경우는 웹 응용 프로그램 내에서만 웹 API 서비스를 노출 하는 경우 서비스를 소비하는 다른 클라이언트가 있고 클라이언트는 다른 웹 응용 프로그램 또는 .Net 응용 프로그램 (Win Forms, WPF, 콘솔, Windows 서비스, 기타)

    예를 들어, 동일한 네트워크 도메인 (인트라넷 내)의 다른 웹 응용 프로그램에서 웹 API 서비스를 사용한다고 가정합니다.이 경우 ASP.Net에서 제공하는 Windows 인증에 의존 할 수 있습니다.

    <authentication mode="Windows" />

    서비스가 인터넷에 노출되면 인증 된 토큰을 각 웹 API 서비스에 전달해야합니다.

    자세한 내용은 다음 기사를 참조하십시오.


3
와! 그것이 내가 대답이라고 부르는 것입니다. 결론을 내립니다. 다음 작업을 수행 할 계획입니다. 1. HTTPS를 통해 사용자 이름과 암호를 받고 로그인 결과와 토큰을 반환하는 로그인 방법으로 계정 컨트롤러를 만듭니다. 2. 클라이언트는 토큰을 저장하고 웹 서버에서 확인한 요청에서 더 이상 HTTPS가 아닌 헤더로 보냅니다. 좋은 접근입니까? 그런 다음 마지막 의심은 토큰 변조 및 만료를 제어하는 ​​방법입니다. 이게 가능해?
루이스 아길라 르

6
@Jupaol 많은 웹 API 개발자와 대화하고 웹 사이트가 없어서 클라이언트가 브라우저를 사용하지 않기 때문에 양식 인증을 사용할 수 없으며 사용자가 모든 장치에서 세계 어느 곳에 나있을 수 있기 때문에 통합 인증을 사용할 수 없습니다 ( 따라서 웹 API), 그래서 나는 무엇을 사용해야합니까?
markmnl

21
이 답변이 왜 그렇게 많은 투표를 받는지 이해가되지 않습니다. ASP.NET 웹 API가 아니라 ASP.NET MVC에 관한 것입니다.
Bastien Vandamme

3
나는 B413의 의견을 되풀이하고이 질문이 특별히 웹 API를 요구한다고 지적하고 싶습니다
Julien

6
이것이 SO에서 가장 많이 투표 된 '잘못된'답변입니까? 대답은 실제로 mvc 웹 응용 프로그램과 매우 다른 웹 API에 대해서는 이야기하지 않습니다! @ B413처럼 나는 완전히 충격을 받았습니다!
stt106

15

당신이에 대해 인증하려면 사용자 이름과 암호인증 쿠키 않고 는 MVC4 권한 부여의 속성은 상자 밖으로 작동하지 않습니다. 그러나 기본 인증 헤더를 승인하기 위해 컨트롤러에 다음 헬퍼 메소드를 추가 할 수 있습니다. 컨트롤러 메소드의 시작 부분에서 호출하십시오.

void EnsureAuthenticated(string role)
{
    string[] parts = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(Request.Headers.Authorization.Parameter)).Split(':');
    if (parts.Length != 2 || !Membership.ValidateUser(parts[0], parts[1]))
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "No account with that username and password"));
    if (role != null && !Roles.IsUserInRole(parts[0], role))
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "An administrator account is required"));
}

클라이언트 측에서이 헬퍼 HttpClient는 인증 헤더를 사용하여를 작성합니다 .

static HttpClient CreateBasicAuthenticationHttpClient(string userName, string password)
{
    var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes(userName + ':' + password)));
    return client;
}

방금 업계 표준을 사용하여 헤더에 자격 증명을 전달하는 간단한 방법을 찾고 있다고 언급하고 싶었습니다. 이 예제는 서버와 클라이언트 측의 기본 사항을 보여 주었으며 내가 필요한 전부였습니다.
da_jokker

9

MVC5 / Web API 프로젝트를 진행 중이며 Web Api 메서드에 대한 권한을 얻을 수 있어야했습니다. 인덱스보기가 처음로드되면 자동으로 생성되는 것으로 생각되는 '토큰'웹 API 메소드를 호출합니다.

토큰을 얻기위한 클라이언트 측 코드 (CoffeeScript)는 다음과 같습니다.

getAuthenticationToken = (username, password) ->
    dataToSend = "username=" + username + "&password=" + password
    dataToSend += "&grant_type=password"
    $.post("/token", dataToSend).success saveAccessToken

성공하면 다음을 호출하여 인증 토큰을 로컬로 저장합니다.

saveAccessToken = (response) ->
    window.authenticationToken = response.access_token

그런 다음 [Authorize] 태그가있는 웹 API 메소드에 대해 Ajax 호출을해야하는 경우 Ajax 호출에 다음 헤더를 추가하기 만하면됩니다.

{ "Authorization": "Bearer " + window.authenticationToken }

어디에서 response.access_token왔을 까. C # 코드에서 설정합니까?
shashwat

'응답'오브젝트는 '토큰'메소드에 의해 리턴됩니다.
ProfNimrod

나는 역할을 조사하지 않았습니다. 이 접근 방식은 액세스 토큰 만 제공하므로 [Authorize] 태그로 장식 된 WebApi 메소드를 호출 할 수 있습니다. 아마도 그 방법 중 하나를 호출하면 역할을 확인할 수 있습니다. stackoverflow.com/questions/19689570/mvc-5-check-user-role 이 도움이 될 수 있습니다.
ProfNimrod

이 솔루션에서 사용자를 실제로 인증하는 위치는 어디입니까?
Craig Brett

/ token 엔드 포인트는 모든 새 웹 API 프로젝트에 대해 자동으로 작성됩니다. 이 뒤에 코드는 사용자가 인증되는 곳입니다. 기존 MVC 프로젝트에 웹 API 컨트롤러를 추가 한 경우 좀 더 복잡합니다.
ProfNimrod
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.