segurança para serviços rest, redes sociais e web 2 · conta data de acesso. 25 oauth ......
TRANSCRIPT
Fabio [email protected]
Segurança para serviços REST, Redes Sociais e Web 2.0
2
Fabio Velloso
Bacharel em Ciência da Computação pela Universidade Federal de São Carlos-UFSCar Fundador do SouJava Desenvolvendo projetos com tecnologia Java desde 96 Professor de SOA e Web Services do curso de Pós-Graduação "Lato-Sensu" em Desenvolvimento de Software para Web da UFSCar Arquiteto de Sistemas na Telefonica
3
Agenda
Introdução
REST e WS
Segurança Web
OAuth, Redes Sociais e REST
OpenID
OpenPTK
4
Como implementar segurança para serviços REST, HyperMidia e Redes Sociais
5
Web Services SOAP
Protocolo SOAP sobre HTTP
WSDL
UDDI
Protocolos de segurança WS-*
REST
Paradigma mais novo
Simples
Recursos
Segurança???
Web Services
6
WS-Security XML Signature XML Encryption XML Key Management (XKMS) WS-SecureConversation WS-SecurityPolicy WS-Trust WS-Federation WS-Federation Active Requestor Profile WS-Federation Passive Requestor Profile Web Services Security Kerberos Binding Web Single Sign-On Interoperability Profile Web Single Sign-On Metadata Exchange Protocol Security Assertion Markup Language (SAML) XACML
Web Services Security (SOAP)
7
Paradigma simples para Web Services Acrônimo para Representational State Transfer Não é um padrão É um estilo de Arquitetura de Software “Um conjunto de regras de design que
identificam os tipos de componentes e conectores que podem ser usados para compor um sistema ou subsistema”
RESTful Web Services
8
Recursos são acessíveis e identificados por URI
URI parameters
/users/{user-id}
http://soujava.org.br/users/323421
Conjunto uniforme de operações padronizadas
Query parameters para localizar outros recursos
http://soujava.org.br/users?id=02115
JAX-RS - Java API for RESTful Web Services
Framework com anotações para RESTful Web Services
Anotações que encapsulam métodos e parâmetros HTTP
Jersey implementação de referência
Suporte a mecanismos de autenticação
HTTPBasicAuthFilter, HTTPDigestAuthFilter
RESTful Web Services
9
JAX-RS - @GET, @POST, @DELETE
@Path("/library") public class Library { @GET @Path("/books") public String getBooks() {...} @GET @Path("/book/{isbn}") public String getBook(@PathParam("isbn") String id) {..}
@DELETE @Path("/book/{id}") public void removeBook(@PathParam("id") String id) {...} }
10
Web como plataforma para sistemas distribuídos
Pensar em Recursos
“Resource-Oriented”
Recurso pode ser qualquer coisa exposta na Web:
Video,Imagens, Documentos
URI referenciando recursos
java.net
www.java.net “Hypermedia as the engine of application state” Redes Sociais
Segurança já disponível para Web
11
Basic authentication
Usuário e senha no Header HTTP, sem criptografia
User:password
Base 64
GET /areaprivada/index.html HTTP/1.1Host: localhostAuthorization: Basic QwxhZATpbjpvcGVuIHNlc2FeOP==
Uso de SSL
12
Basic authentication
Java EE Security
@RolesAllowedAcesso permitido a usuários com papel adequado
Exemplo:
@GET
@Path("/Secure")
@RolesAllowed("admin")
@Produces("text/plain")
public String getMessage(@Context HttpHeaders headers){
return "Olá JavaOne Brasil";
}
13
Basic authentication
web.xml
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Test</realm-name>
</login-config>
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>user</role-name>
</security-role>
tomcat-users.xml
<user password="fabio" roles="manager,admin" username="fabio"/>
<user password="tomcat" roles="manager,admin" username="tomcat"/>
14
Basic authentication
Base 64
private String getCredentials(HttpHeaders headers) {
String authorization = headers.getRequestHeader("authorization").get(0);
authorization = authorization.substring("Basic ".length());
String[] data = new String(Base64.base64Decode(authorization)).split(":");
String username = data[0];
String password = data[1];
}
15
Basic authentication
Problemas:
Não é criptografia
Sem integridade
Sem confidencialidade
Senhas trafegando pela rede
Chave compartilhada
Controle de acesso fraco
Log e auditoria de acesso dificultada
Digest e SSL
Mecanismos de delegação
16
OAuth
Protocolo aberto para permitir a autorização usando uma API segura, simples e padronizada para aplicativos desktop e web
Compartilhar dados (recursos), com vários usuários, sem compartilhar sua identidade
RFC 5849 – OAuth v1.0 - Internet Engineering Task Force
Possibilita proteção de acesso a recursos Web
Facebook, Twitter, Linkedin, SalesForce
Token e Secret para acesso a aplicação/recurso
Token de requisição e Token de acesso
Token pode ser revogado a qualquer momento
Autorização para cada request facilita log e auditoria
17
OAuth – Entidades
Service ProviderProvedor do recurso protegido
ConsumerA aplicação que requisita acesso a um recurso protegido
Resource OwnerO proprietário do recurso protegido hospedado no servidor.Controla e aprova acesso
18
19
OAuth Token e CallBack
20
Jersey e OAuth
Suporte ao protocolo v1.0a Módulos maven oauth-client-{version}.jar
Filtro para anexar OAuth Header nas requisições oauth-server-{version}.jar
Geração e tratamento de Tokens oauth-signature-{version}.jar
Suporte a assinaturas OauthHMAC_SHA1, PLAINTEXT, RSA_SHA1
Projetos com NetBeans e Maven Adicionar dependências
GroupId: com.sun.jersey.contribs.jersey-oauthArtifactId: oauth-server Version: ${jersey-version}
21
Jersey e OAuth
OAuthSecrets OAuth secrets a serem utilizados na assinatura das requisições
OAuthParametersParâmetros utilizados nas requisiçõesChave da aplicação/usuário (CONSUMER_KEY)Método de assinatura ("HMAC-SHA1")Versão
ClientCliente que acessa serviço/recurso
OAuthClientFilterAssina os requests com assinatura OAuthAdiciona um Header com os parametros OAuth
22
OAuth Request Token
https://site_destino/oauth/requestToken
Exemplo:
– https://api.linkedin.com/uas/oauth/requestToken
authorization OAuth oauth_nonce="a912e229-2488-4a69-ad31-7f3cc7390cd4",
oauth_callback="http%3A%2F%2Flocalhost%2Foauth_callback",oauth_consumer_key="c6z48v4MU1QBCpm6R9XshNfVVWmV3RzgwoZFZ9F", oauth_signature_method="HMAC-SHA1",
oauth_version="1.0", oauth_signature="TXJwbUzeX%2BvWTZqenVGSxvdmB83D",
oauth_timestamp="1291596497"
Adiciona um único Header HTTP chamado authorization
23
OAuth Request Token
OAuthSecrets oAuthSecrets = new OAuthSecrets().consumerSecret(Definitions.CONSUMER_SECRET);
OAuthParameters oAuthParams = new OAuthParameters().consumerKey(Definitions.CONSUMER_KEY).
signatureMethod("HMAC-SHA1").version("1.0");
client.addFilter( new OAuthClientFilter(client.getProviders(), oAuthParams, oAuthSecrets));
Form response = client.resource(Definitions.REQUEST_TOKEN_URL).post(Form.class);
Define OAuthSecret e OAuthParameterscom os valores gerados pelo
servidor dos recursos
Assina o request Assina o request com assinatura OAuth Adiciona o Header “authorization”
com os parâmetros OAuth
Executa POST para pedir RequestToken
24
OAuth Authorize URL
https://site_destino/oauth/authorize
Exemplo:
https://www.linkedin.com/uas/oauth/authorize?
oauth_token=6451ca51-6a82-410e-a3f3-f7d837d856fc
Retorno para callback url definida
Aplicação
Conta
Data de Acesso
25
OAuth Authorize URL
Form response = client.resource(Definitions.REQUEST_TOKEN_URL).post(Form.class);
Definitions.setToken(response.getFirst(OAuthParameters.TOKEN),
response.getFirst(OAuthParameters.TOKEN_SECRET), false);
Response.seeOther(UriBuilder.fromPath(Definitions.AUTHORIZE_URL).
queryParam(OAuthParameters.TOKEN, response.getFirst(OAuthParameters.TOKEN)).build()).build();
POST executado para pedir um RequestToken
Armazena os valores de Retornados (RequestToken e TokenSecret)
RequestToken“oauth_token”
Redireciona Para página deAutorização doServiço
26
OAuth Access Token
https://site_destino/oauth/accessToken
Exemplo:https://api.linkedin.com/uas/oauth/accessToken
Authorization: OAuth oauth_nonce="wm2h9DH3Njoe62ezioNQS0qPfD11MH4w4paJufkk", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1259178208", oauth_consumer_key="ABCDEFGHIJKLMNOPQRSTUVQXYZ", oauth_token="94ab03c4-ae2c-45e4-8732-0e6c4899db63", oauth_verifier="27871", oauth_signature="srWAOowk6Tk4irC9pEMUa7Tx%2BBc%3D", oauth_version="1.0"
27
OAuth Access Token
OAuthSecrets oAuthSecrets = new OAuthSecrets().consumerSecret(Definitions.CONSUMER_SECRET).
tokenSecret(Definitions.getTokenSecret());
OAuthParameters oAuthParams = new OauthParameters().consumerKey(Definitions.CONSUMER_KEY).
token(Definitions.getToken()).signatureMethod("HMAC-SHA1").version("1.0").verifier(verifier);
client.addFilter(new OAuthClientFilter(client.getProviders(), oAuthParams, oAuthSecrets));
Form response = client.resource(Definitions.ACCESS_TOKEN_URL).post(Form.class);
Definitions.setToken(response.getFirst(OAuthParameters.TOKEN),
response.getFirst(OAuthParameters.TOKEN_SECRET), true);
return Response.seeOther(UriBuilder.fromResource(ShowResource.class).build()).build();
RequestTokenSetado
no passo anterior
Retorna paraClasse/método que
ira acessar o recurso
Armazena os valores retornados (AccessToken e TokenSecret)
Define OAuthSecret e OAuthParameterscom os valores gerados pelo
servidor dos recursos
Código de verificação
associado ao RequestToken
28
OAuth - Acessar Recurso
Client client = Client.create();OAuthSecrets oAuthSecrets = new OAuthSecrets().consumerSecret(Definitions.CONSUMER_SECRET)
.tokenSecret(Definitions.getTokenSecret());OAuthParameters oAuthParams = new OAuthParameters().consumerKey(Definitions.CONSUMER_KEY)
.token(Definitions.getToken()).signatureMethod("HMAC-SHA1").version("1.0");
client.addFilter(new OAuthClientFilter(client.getProviders(), oAuthParams, oAuthSecrets));ClientResponse response = client.resource(SettingsBack.URL).get(ClientResponse.class);
Requisição
Authorization: OAuth oauth_nonce="LpggMEZQYFkdTmrw0OixdZLMc6DdjNWDywsIULxVRwo", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1259182582", oauth_consumer_key="ABCDEFGHIJKLMNOPQRSTUVQXYZ", oauth_token="f862f658-ad89-4fcb-995b-7a4c50554ff6", oauth_signature="udXNypHc%2BbaM0FP1xRdXeyKI2%2Fo%3D", oauth_version="1.0"
Assina o request com assinatura OAuth Adiciona o Header
“authorization” com os parâmetros OAuth
Define OAuthSecret e OAuthParameterscom os valores gerados pelo
servidor dos recursos
AccessToken armazenadono passo anterior
ClienteResponse com dados dorecurso acessado
29
OAuth
30
OAuth Server – Gerar Tokens
DefaultOAuthProvider defaultOAuth = new DefaultOAuthProvider();
Consumer registerConsumer = defaultOAuth.registerConsumer("owner", attributes);
String CONSUMER_KEY = registerConsumer.getKey();
String CONSUMER_SECRET = registerConsumer.getSecret();
Armazenar dados
Relacionar CONSUMER_KEY a aplicação
MultivaluedMap com informações adicionais sobre o consumidorNome, URI, Descrição...
31
OAuth Server – RequestToken
@Path("/requestToken")
public class RequestTokenResource {@POST@Produces(MediaType.APPLICATION_FORM_URLENCODED) public javax.ws.rs.core.Response getHtml(@HeaderParam("authorization") String authorization) {
MultivaluedMap<java.lang.String, java.lang.String> attributes;
// obter do Header authorization "oauth_consumer_key"
// Validar se Consumer_Key existe, validar hash
OAuthToken requestToken = defaultOAuth.newRequestToken(oauth_consumer_key, callbackUrl, attributes);
String ret = OAuthParameters.TOKEN+"="+requestToken.getToken() +"&"+OAuthParameters.TOKEN_SECRET+"="+requestToken.getSecret();
return Response.ok(ret).build();
• Autorizar acesso no serviço (Owner logado)
Header com os parametros OAuth
Header com os parametros OAuth
Token e TokenSecretno corpo da
resposta
Geração do RequestToken
Parâmetros para Indicar nível de
acesso por exemplo.Read, ReadWrite
32
OAuth Server – AccessToken
@Path("/accessToken")
public class AccessTokenResource {@POST@Produces(MediaType.APPLICATION_FORM_URLENCODED) public javax.ws.rs.core.Response getHtml(@HeaderParam("authorization") String authorization) {
// obter do Header authorization “oauth_token”// Validar se Consumer_Key existe, validar hash
OAuthToken accessToken = defaultOAuth.newAccessToken(oauth_token, defaultOAuth.authorizeToken(oauth_token, userPrincipal, roles));
string ret = OAuthParameters.TOKEN+"="+accessToken.getToken() +"&"+OAuthParameters.TOKEN_SECRET+"="+accessToken.getSecret(); return Response.ok(ret).build();
Header com os parametros OAuth
Header com os parametros OAuth
Token e TokenSecretno corpo da resposta
Geração do AccessToken
Principal identificando o owner einformações adicionais sobre
o consumer:URI, nome e descriçãoVerifierPara
CallbackURL
33
Protegendo o recurso
Validar tokens e assinaturas no recursoAcopla lógica de negócio com autorização
Usar @ResourceFiltersDefine a lista de filtros associadas com o recursoResourceFilters é um singletonAplicável a classe ou métodoFiltros precisam implementar ResourceFilter
@DELETE @Path("/book/{id}")@ResourceFilters(value = {OAuthAuthorizationRequiredFilter.class,
OAuthAccessTokenRequiredFilter.class,OAuthNonceFilter.class})
public Response recursoProtegido {.....}
34
Filtro para o recurso
public class OAuthAccessTokenRequiredFilter implements ResourceFilter {
@Override public ContainerRequestFilter getRequestFilter() { return new ContainerRequestFilter() {
public ContainerRequest filter(ContainerRequest cr) { HashMap<String, String> oauthValues =
OauthHeaderHelper.extractOauthParamsFromAuthorizationHeader( cr.getHeaderValue(′′Authorization′′));
if(!oauthValues.containsKey(′′oauth_token′′)) { throw new WebApplicationException( Response.status(Status.UNAUTHORIZED) .
type(MediaType.TEXT_PLAIN) .entity(′′No oauth_token in request.′′).build());}
} return cr; } };}
35
OAuth 2
DRAFT - Abril 2010 Especificação final prevista para o final do ano OAuth Web Resource Authorization Protocol (WRAP) foi base Incompativel com OAuth 1.0 Torna obsoleta a especificação OAuth 1.0 Suporte parcial no Facebook e Twitter Facebook Graph API e Twitter com suporte parcial Processo simplificado sem RequestToken Sem assinatura OAuth
SSL Sem Token Secret
36
OpenID
Protocolo que possibilita o armazenamento de IDs ou credenciais (usuário e senha) em um repositório centralizado
Compartilha com um ou mais consumidores
Provider responsável por autenticar e informar consumidores
Suportado por Google, Yahoo!, Flickr, Facebook, Verisign
OpenID providers - Google, Yahoo e AOL
OpenID
Compartilhar uma identidade com diferentes consumidores
OAuth
Compartilhar dados (recursos), com vários usuários, sem compartilhar sua identidade
Podem trabalhar em conjunto
37
OpenPTK
Open Source User Provisioning Toolkit
Gerenciamento de usuários com interface Web Services (REST e SOAP), Portlets, Taglibs e APIs
Suporta vários repositórios de identidade
LDAP
Banco de Dados
Autenticação e autorização na versão 2.0 (em desenvolvimento)
Configuração em arquivos XML
https://openptk.dev.java.net/
38
OpenPTK
39
OpenPTK - Autorização
1 - Request
Session/Principal:Principal com usuário
Operation: CREATE, READ, UPDATE, DELETE, etc.
Target ou Resource: URI a ser acessada
2 - Enforcer - ServletFilter que processa o Request
3 - Decider – Avalia o direito de acesso baseado nas políticas e retorna true ou false
4 – Policies – políticas de acesso utilizadas pelo Decider
40
OpenPTK - Configuração
<Policy id="System" environment="ENGINE" mode="inbound" effect="allow"> <Properties> <Property name="policy.description" value="System user access"/> </Properties> <Session> <Types> <Type id="SYSTEM"/> </Types> </Session> <Targets> <Target id="contexts" uri="/resources/contexts/*"> <Operations> <Operation id="CREATE"/> <Operation id="READ"/> <Operation id="UPDATE"/> <Operation id="DELETE"/> <Operation id="SEARCH"/> </Operations> </Target> <Target id="engine" uri="/resources/engine/*"> <Operations> <Operation id="READ"/> </Operations> </Target> </Targets></Policy>
Habilita usuários SYSTEM a executar todas
operações em contexts
Habilita usuários SYSTEM a executar leitura
em engine
41
Conclusão
Frameworks e API's para recursos Web OAuth para autenticação OpenID para identificação na rede
OAuth possibilita compartilhar dados (recursos), com vários usuários, sem compartilhar sua identidade
Versão 1.0 disponível em APIs e serviços como FaceBook, Linkedin, Twitter
Especifição OAuth 2.0 draft
Facebook Graph API e Twitter com suporte parcial
OpenPTK para provisionar usuários
42
Obrigado
Perguntas???
43
Palestra
www.fabiovelloso.com.br/palestras/javaonebr2010.pdf
Código exemplo
www.fabiovelloso.com.br/palestras/rest-sec-j1br.zip
[email protected]• Twitter
@fabiovelloso
44
Transforme seu processo em Rest com JAX-RS Horário: 14:00 - 14:45 Sala: Auditório 5
Segurança e insegurança em aplicações Internet Java EE
Horário: 15:00 - 15:45
Sala: Auditório 4
Servlet 3.0 – Expansível, Assíncrono e Fácil de Usar
Horário: 16:15 - 17:00 Sala: Auditório 1
Sessões relacionadas
45
46
OpenID