CSRF token generation - csrf

This is a question about generating CSRF tokens.
Usually I'd like to generate a token based off of a unique piece of data associated with the user's session, and hashed and salted with a secret key.
My question is in regards to generating tokens when there is NO unique user data to use. No sessions are available, cookies are not an option, IP address and things of that nature are not reliable.
Is there any reason why I cannot include the string to hash as part of the request as well?
Example pseudocode to generate the token and embed it:
var $stringToHash = random()
var $csrfToken = hash($stringToHash + $mySecretKey)
click me
Example server-side validation of the CSRF token
var $stringToHash = request.get('key')
var $isValidToken = hash($stringToHash + $mySecrtKey) == request.get('csrfToken')
The string being used in the hash would be different on each request. As long as it was included in each request, the CSRF token validation could proceed. Since it is new on each request and only embedded in the page, outside access to the token would not be available. Security of the token then falls to the $mySecretKey being known only to me.
Is this a naive approach? Am I missing some reason why this cannot work?
Thanks

Is there any reason why I cannot include the string to hash as part of the request as well?
CSRF tokens have two parts. The token embedded in the form, and a corresponding token somewhere else, be it in a cookie, stored in a session or elsewhere. This use of elsewhere stops a page being self contained.
If you include the string to hash in the request, then the request is self contained, so copying the form is all an attacker needs to do, as they have both parts of the token, and thus there is no protection.
Even putting it in the form URL means that it's self contained, the attacker simply copies the form and the submission URL.

Try base64_encode(openssl_random_pseudo_bytes(16)).
https://github.com/codeguy/php-the-right-way/issues/272#issuecomment-18688498 and I used it for my form example in https://gist.github.com/mikaelz/5668195

CSRF token meant to prevent (unintentional) data modifications, which are usually applied with POST requests.
Thus, you must include CSRF token for each request that changes data (either GET or POST request).
My question is in regards to
generating tokens when there is NO
unique user data to use. No sessions
are available, cookies are not an
option, IP address and things of that
nature are not reliable.
Then simply create a unique user id for each visitor.
Include that id in a cookie or in the URLs (if cookies are disabled).
Edit:
Consider the following event:
You have logged-in to your facebook account and then entered to some arbitrary website.
In that website there's a form that you submit, which tells your browser to send a POST request to your facebook account.
That POST request may change your password or add a comment etc, because that the facebook application recognized you as a registered & logged-in user. (unless there's another blocking mechanism, like CAPTCHA )

I think the best idea to make hash based on HMAC, i.e. make hash encrypted by some password this sequence: username+user_id+timestamp. Each request the hash must be different, timestamp must be if you don't want to get simple replay the hash in attack.

You simply just need the same "token" in the URL/form and in the cookie. This means that you could have your page setting the token cookie to whatever it wants to (preferably some random value) by JavaScript and then just pass the very same value in all requests that goes to your server (as a URI ?param or form-field). No need to have your server generating the cookie.
This is safe as long as we trust that the browser doesn't allow pages from a domain to edit/read cookies for other domains, and this is assumed to be quite secure today.
Having your server generating the token will assume that this token can be safely transmitted to your browser without being picked up by any CSRF attempts (why take the risk?). Though you could put more logic into a server generated token, but to prevent CSRF there is no need.
(If I'm wrong here please let me know)

I wanna say your approach works, because CSRF attack is the attacker utilizing victim's browser to forge a logged-in status, why can they do so? because on most server side the session check is based on a SessionID in cookie, and cookie is a piece of data will be automatically attached to a HTTP request sent to server.
Therefore, there are two key factors for defending CSRF
Generate a challenge token, and require client to pass it to server in a non-cookie way, either URL param or POST form is ok.
Keep the token safe as what you did to the SessionID, for instance, using SSL.
I recommend reading CSRF Prevention Cheat Sheet

There are multiple implementation of CSRF token. The key thing is whether this csrf token is generated on the client side or server side. Because the implementation changes drastically for these two scenarios and the entropy of the token as well.
For server side, SecureRandom is the preferred way but in your case you want to generate the CSRF token before any user is identified, window.crypto provides this functionality where you can generate a unguessable enough string to be used for CSRF token.

With the help of CSRF token we can sure incoming request is authenticated (know user not hacker)
Please note i have required below approach but google can't help me even on stackoverflow i did't get mentioned code below but after collection of stackoverflow answer i have made my day. So it's useful for further searching/ specially for beginners
I have described below Spring MVC with Spring Interceptor
Note - I have used google cache to store salt in cache for re verification
below dependency need to add pom.xml
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.0-jre</version>
</dependency>
below HandlerInterceptorAdapter implemention
package com.august.security;
import java.security.SecureRandom;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
public class CsrfSecurity extends HandlerInterceptorAdapter {
List<String> urlList= new LinkedList<>();
private static final String CSRF_TAG = "CSRF-CHECK";
#SuppressWarnings("unchecked")
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handleer)
throws Exception {
System.out.println("Inside Pre Handler");
String reqUrl = request.getRequestURI().toString();
System.out.println("Request URL : " + reqUrl);
String ipAddress = request.getHeader("X-FORWARDED-FOR");
if (ipAddress == null) {
ipAddress = request.getRemoteAddr();
}
//local host url http://localhost:8080/august/
if (request.getRequestURI().contains("/august/")) {
System.out.println("pre handler return true");
//it will return and next executed postHandelr method
//because of on above url my webApplication page working
return true;
}
if (ignoreUrl().contains(request.getRequestURI())) {
System.out.println("inside ignore uri");
return true;
} else {
System.out.println("CSRF Security intercepter preHandle method started.......");
String salt = request.getParameter("csrfPreventionSalt");
HttpSession sessionAttribute = request.getSession();
Cache<String, Boolean> csrfPreventionSalt = (Cache<String, Boolean>) sessionAttribute
.getAttribute("csrfPreventionSalt");
if (csrfPreventionSalt == null) {
System.out.println("Salt not matched session expired..");
parameterValuesPrint(request, "saltCacheNotFound");
response.sendRedirect("error");
return false;
} else if (salt == null) {
parameterValuesPrint(request, "noSaltValue");
System.out.println("Potential CSRF detected !! inform ASAP");
response.sendRedirect("error");
return false;
} else if (csrfPreventionSalt.getIfPresent(salt) == null) {
System.out.println("saltValueMisMatch");
System.out.println("Potential CSRF detected !! inform ASAP");
response.sendRedirect("error");
} else {
request.setAttribute("csrfPreventionSalt", csrfPreventionSalt);
}
return true;
}
}
#SuppressWarnings("unchecked")
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) {
System.out.println("Inside post Handler");
System.out.println("CSRF Security key generator method started");
try {
//localhost url http://localhost:8080/august/
//api is my controller path so no need to genrate token for api
if (request.getRequestURI().contains("/august/api/")) {
System.out.println("No need to genrate salt for api");
} else {
HttpSession sessionAttribute = request.getSession();
Cache<String, Boolean> csrfPreventionSaltCache = (Cache<String, Boolean>) sessionAttribute
.getAttribute("csrfPreventionSalt");
System.out.println("csrfPreventionSaltCache ::: " + csrfPreventionSaltCache);
if (csrfPreventionSaltCache == null) {
csrfPreventionSaltCache = CacheBuilder.newBuilder().maximumSize(5000)
.expireAfterWrite(20, TimeUnit.MINUTES).build();
request.getSession().setAttribute("csrfPreventionSaltCache", csrfPreventionSaltCache);
}
String salt = RandomStringUtils.random(20, 0, 0, true, true, null, new SecureRandom());
System.out.println("csrfPreventionSalt genrated ::: " + salt);
csrfPreventionSaltCache.put(salt, Boolean.TRUE);
if (modelAndView != null) {
System.out.println("Model and view not null and salt is added in modelAndView");
modelAndView.addObject("csrfPreventionSalt", salt);
}
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion : ");
if (ex != null) {
System.out.println("exception : " + ex.getMessage());
ex.printStackTrace();
}
}
private List<String> ignoreUrl() {
if(urlList == null) {
urlList.add("/august/error");
//add here your ignored url.
}
return urlList;
}
private void parameterValuesPrint(HttpServletRequest request, String err) {
StringBuilder reqParamAndValue = new StringBuilder();
Enumeration<?> params = request.getParameterNames();
while (params.hasMoreElements()) {
Object objOri = params.nextElement();
String param = (String) objOri;
String value = request.getParameter(param);
reqParamAndValue = reqParamAndValue.append(param + "=" + value + ",");
}
System.out.println(CSRF_TAG + " " + err + "RequestedURL : " + request.getRequestURL());
}
}
Below is Interceptor registration with spring context
package com.august.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import com.august.security.CsrfSecurity;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages="com.august")
public class SpringConfiguration extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
//viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Bean
public CsrfSecurity csrfSecurity() {
return new CsrfSecurity();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CsrfSecurity());
}
}
below is my controller
package com.august.v1.appcontroller;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class HomeController {
#Autowired
HttpSession httpSession;
#RequestMapping("/")
public String index(Model model) {
httpSession.invalidate();
System.out.println("Home page loaded");
return "index";
}
}
below is my index.jsp jsp page
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" isELIgnored="false"%>
//don't forget to add isELIgnored="false" on old(version) jsp page because of i
//have wasted 1 hour for this
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>ADS Home</title>
</head>
<body>
<h1>${csrfPreventionSalt}</h1>
<input type="hidden" name="csrfPreventionSalt" value=${csrfPreventionSalt}>
</body>
</html>
For Understanding about CSRF - CSRF explanation

CSRF utilizes the user's session, so, if you don't have one, there is no CSRF.

Related

Redirection issue in Oauth2

I'm developing simple microservices with Oauth2 with keycloak as authorization server.
Following is the code which returns list of albums when hitting the url: - http://localhost:8087/albums
#Controller
public class AlbumController {
#Autowired
OAuth2AuthorizedClientService oauthService;
#Autowired
RestTemplate restTemplate;
#GetMapping("/albums")
public String getAlbums(Model model,#AuthenticationPrincipal OidcUser principal,Authentication auth) {
OidcIdToken token=principal.getIdToken();
String tokenValue=token.getTokenValue();
Authentication authentication=SecurityContextHolder.getContext().getAuthentication();
OAuth2AuthenticationToken oauthToken=(OAuth2AuthenticationToken) authentication;
OAuth2AuthorizedClient client=oauthService.loadAuthorizedClient(oauthToken.getAuthorizedClientRegistrationId(), oauthToken.getName());
String jwtAccessToken=client.getAccessToken().getTokenValue();
String url="http://localhost:9091/albums";
HttpHeaders headers=new HttpHeaders();
headers.add("Authorization", "Bearer "+jwtAccessToken);
HttpEntity<List<AlbumsRest>> entity=new HttpEntity<List<AlbumsRest>>(headers);
ResponseEntity<List<AlbumsRest>> responseEntity=restTemplate.exchange(url, HttpMethod.GET, entity, new ParameterizedTypeReference<List<AlbumsRest>>() {
});
List<AlbumsRest> albums=responseEntity.getBody();
model.addAttribute("Albums", albums);
return "albums";
}
}
Following is my application.properties file :-
server.port=8087
spring.security.oauth2.client.registration.mywebclient.client-id=tcs
spring.security.oauth2.client.registration.mywebclient.client-secret=2KcMN6xsmJH235k6TlLXUXj3iY3sAl8i
spring.security.oauth2.client.registration.mywebclient.scope=openid,profile,roles
spring.security.oauth2.client.registration.mywebclient.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.mywebclient.redirect-uri=http://localhost:8087/login/oauth2/code/mywebclient
spring.security.oauth2.client.provider.mywebclient.authorization-uri=http://localhost:7070/auth/realms/developer/protocol/openid-connect/auth
spring.security.oauth2.client.provider.mywebclient.token-uri=http://localhost:7070/auth/realms/developer/protocol/openid-connect/token
spring.security.oauth2.client.provider.mywebclient.jwk-set-uri=http://localhost:7070/auth/realms/developer/protocol/openid-connect/certs
spring.security.oauth2.client.provider.mywebclient.user-info-uri=http://localhost:7070/auth/realms/developer/protocol/openid-connect/userinfo
spring.security.oauth2.client.provider.mywebclient.user-name-attribute=Utkarsh0911
Whenever I'm hitting the url http://localhost:8087/albums, it performs too many redirections and finally end up on a page with message "This Page isn't working".
this loop usually occurs when the redirect URL is not defined as permitted in the application. Please check here:
https://dzone.com/articles/spring-boot-how-to-solve-oauth2-err-too-many-redir

Does spring-boot-admin support sso?

I'm trying to integrate spring-boot-admin with my corporate SSO, does spring-boot-admin support sso login? I cannot find documentation about it.
I got it to work. Steps to implement:
Create controller with an endpoint that the sso provider will call.
In the endpoint, put the logic for sso integration,
On success, redirect to /applications
On failure, throw an exception
#Controller
public class SsoIntegration {
// this does addition authentication stuff, like sets up the
// right authorities...etc
#Autowired
private AuthenticationProvider authenticationProvider;
// my sso provider creates a vanity url that redirects to
// this endpoint and passes 2 request params using POST
#RequestMapping(value={"/sso"}, method = {RequestMethod.POST})
public String ssologin (
#RequestParam(name="param1") String param1,
#RequestParam(name="param2") String param2 )
{
// do your sso integration logic here
// eg...
SsoUtil util = new SsoUtil();
String userInfo = util.decrypt(param1, param2, ...);
...
if (authenticationProvider.authenticate( userInfo )) {
Authentication postAuthentication = ...// populate your successfully authenticated user
// these next lines are the important stuff
// 1. set the postAuthentication into the security context
SecurityContextHolder.getContext().setAuthentication(postAuthentication);
// 2. redirect to the applications page
return "redirect:/applications";
}
// authentication failed, throw an exception...
throw new RuntimeException ("Sso Authentication failed");
}
}

C#.Net RestSharp client - passing auth token

I am writing a REST client in C#.Net using RestSharp. There are two API calls - one is "Auth" call and second is "getKey" call. The "Auth" call throws back a "Auth token"in the response, and I'd like to parse that token from the response, and pass it as an header to the second "getkey" call. Please advise with examples
I have given some sample to achieve your scenario. Please use the below example and do the modification as per your requirement.
RestUtils Class:
Add the Request Header, If your application is expected some additional headers.
class RestUtils
{
private static readonly RestClient _restClient = new RestClient();
public static void SetBaseURL(String host)
{
_restClient.BaseUrl = new Uri(host);
}
public static string GetResponse(String endpoint, String token)
{
var request = new RestRequest(endpoint, Method.GET);
request.AddHeader("Accept", "application/json");
request.AddHeader("Authorization", token);
IRestResponse response = _restClient.Execute(request);
return response.Content;
}
public static string GetToken(String endpoint)
{
var request = new RestRequest(endpoint, Method.GET);
request.AddHeader("Accept", "application/json");
IRestResponse response = _restClient.Execute(request);
return response.Content;
}
}
TestClass:
In your test class you can add the below steps and you can get the result as expected. First two lines will be executed and give the authentication token as output. So, you can use the retrieved token in the subsequent lines for other API. In another way, you can create one property class and set the retrieved token value .So, that you can access the token from various class.
//Specify the Base URI of your Token Specific API
RestUtils.SetBaseURL("https://login.microsoftonline.com/");
//Specify the End Point of your Token Specific API
String token = RestUtils.GetToken("/oauth2/token");
//Specify the Base URI of your actual Test API
RestUtils.SetBaseURL("XXXXXXX");
String response = RestUtils.GetResponse(token);

Wicket 6.x https with other host

I have a webpage with a area where users can login. This area
www.host.com/mypage/myarea
should be under https.
The problem is that my https is running on a another host:
www.something-foo.host.com/mypage/myarea
. (loadbalancer stuff...??? I dont know why)
My try is to annotate the Pages with #RequireHttps, an than rewrite the urls of the Pages.
But how and where? Has someone please an example?
Thanks for your help.
Well if you really want to this with Wicket your best option would be to write an implementation of IRequestMapperDelegate and set them during the onInit() process of your WicketApplication.
To give you an idea how to do this I've written an example of raping the HttpsMapper of Wicket:
setRootRequestMapper(new HttpsMapper(getRootRequestMapper(), new HttpsConfig(8080, 8443)) {
private final static String SUBDOMAIN = "www.something-foo.";
#Override
protected Scheme getSchemeOf(Request request) {
HttpServletRequest req = (HttpServletRequest) ((WebRequest) request).getContainerRequest();
// well that's basically cheating and not so nice... but we're not allowed to overwrite mapRequest()
// but that means that every request that doesn't start with the subdomain will be treated as HTTP aka
// insecure.
if (req.getServerName().startsWith(SUBDOMAIN) == false) {
return Scheme.HTTP;
}
return super.getSchemeOf(request);
}
#Override
protected String createRedirectUrl(IRequestHandler handler, Request request, Scheme scheme) {
// stolen from super implementation
HttpServletRequest req = (HttpServletRequest) ((WebRequest) request).getContainerRequest();
String url = scheme.urlName() + "://";
// except the part where we insert the subdomain
url += SUBDOMAIN;
url += req.getServerName();
if (!scheme.usesStandardPort(getConfig())) {
url += ":" + scheme.getPort(getConfig());
}
url += req.getRequestURI();
if (req.getQueryString() != null) {
url += "?" + req.getQueryString();
}
return url;
}
});
Depending on your question I can't really determine if this is a good solution ... it really depends on how many frameworks are working on top of Wicket. Since you didn't mention anything else I'm assuming none.

Twitter 4j with Netbeans

First time poster, but I'm really stuck.
I'm working on a little project and I'm trying to send out a tweet using a netbeans project. I'm using twitter4j and it seems like things have recently changed to where you have to use their OAuth function. I've created an application on twitter and tried some code but I keep getting this error:Exception in thread "main" connect timed outRelevant discussions can be on the Internet at:
http://www.google.co.jp/search?q=b2b52c28 or
http://www.google.co.jp/search?q=1b442895
TwitterException{exceptionCode=[b2b52c28-1b442895 b2b52c28-1b44286b], statusCode=-1, retryAfter=-1, rateLimitStatus=null, featureSpecificRateLimitStatus=null, version=2.2.5}
at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:200)
at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:65)
at twitter4j.internal.http.HttpClientWrapper.post(HttpClientWrapper.java:102)
at twitter4j.TwitterImpl.post(TwitterImpl.java:1929)
at twitter4j.TwitterImpl.updateStatus(TwitterImpl.java:433)
at login.Login.start(Login.java:36)
at login.Login.main(Login.java:63)
Caused by: java.net.SocketTimeoutException: connect timed out
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:75)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:157)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391)
at java.net.Socket.connect(Socket.java:579)
at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:388)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:483)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:213)
at sun.net.www.http.HttpClient.New(HttpClient.java:300)
at sun.net.www.http.HttpClient.New(HttpClient.java:316)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:992)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:928)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:846)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1087)
at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:158)
... 6 more
Java Result: 1
I'm not entirely sure what I'm doing wrong. Below is the code I've tried.
package login;
import java.io.IOException;
import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
public class Login {
private final static String CONSUMER_KEY = "******";
private final static String CONSUMER_KEY_SECRET =
"******";
public void start() throws TwitterException, IOException {
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_KEY_SECRET);
// here's the difference
String accessToken = getSavedAccessToken();
String accessTokenSecret = getSavedAccessTokenSecret();
AccessToken oathAccessToken = new AccessToken(accessToken,
accessTokenSecret);
twitter.setOAuthAccessToken(oathAccessToken);
// end of difference
twitter.updateStatus("Hi, im updating status again from Namex Tweet for Demo");
System.out.println("\nMy Timeline:");
// I'm reading your timeline
ResponseList list = twitter.getHomeTimeline();
/* for (Status each : list) {
System.out.println("Sent by: #" + each.getUser().getScreenName()
+ " - " + each.getUser().getName() + "\n" + each.getText()
+ "\n");
}*/
}
private String getSavedAccessTokenSecret() {
// consider this is method to get your previously saved Access Token
// Secret
return "oC8tImRFL6i8TuRkTEaIcWsF8oY4SL5iTGNkG9O0Q";
}
private String getSavedAccessToken() {
// consider this is method to get your previously saved Access Token
return "102333999-M4W1Jtp8y8QY8RH7OxGWbM5Len5xOeeTUuG7QfcY";
}
public static void main(String[] args) throws Exception {
new Login().start();
}
}
Could I suggest an alternative route..
I have recently been messing around with twitter4j and I approached this slightly differently - I found a nice and easy way to authenticate the client using a ConfigurationBuilder object and passing this to the factory that is getting the instance of the Twitter object you need.
package main;
import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.TwitterStream;
import twitter4j.TwitterStreamFactory;
import twitter4j.conf.ConfigurationBuilder;
public class Base {
protected Twitter twitter;
//protected TwitterStream twitterStream;
private ConfigurationBuilder configBuilder;
public Base(){
configBuilder = new ConfigurationBuilder();
configBuilder.setDebugEnabled(true);
configBuilder.setOAuthConsumerKey("[consumer key here]");
configBuilder.setOAuthConsumerSecret("[consumer secret key here]");
configBuilder.setOAuthAccessToken("[OAuthAccessToken here]");
configBuilder.setOAuthAccessTokenSecret("[secret OAuthAccessToken here]");
//use the ConfigBuilder.build() method and pass the result to the TwitterFactory
TwitterFactory tf = new TwitterFactory(configBuilder.build());
//you can now get authenticated instance of Twitter object.
twitter = tf.getInstance();
}
}
You could then extend this class with sub classes that implement the functionality you require or just create the ConfigurationBuilder/TwitterFactory/Twitter objects elsewhere in your code.
Below I have implemented a class that creates status' and can return the Status object that holds additional information such as createdAt() and the ID etc etc.
package main;
import twitter4j.Status;
import twitter4j.TwitterException;
public class StatusUpdater extends Base{
public StatusUpdater(){}
public Status updateStatus(String statusToUpdate) throws TwitterException{
Status status = twitter.updateStatus(statusToUpdate);
System.out.println("statusToUpdate: " + status + ".");
return status;
}
}
Then you can use the following statement to create the status. This can be done from mbean/ejb/servlet etc.
try {
StatusUpdater statusUpdater = new StatusUpdater();
String statusTextToSet = "test status";
Status updatedStatus = statusUpdater.updateStatus(statusTextToSet);
System.out.println("Created at: " + updatedStatus.getCreatedAt());
} catch (TwitterException tex) {
System.out.println(tex.getErrorMessage());
}
More info on the configuration process here
Your code looks ok. Have you confirmed your definitely using the correct consumer key and secret for your app? Try twitter.verifyCredentials() to see if you get the same error, or a more specific error.
If you're correcting to the net via a proxy, you will need to include your proxy settings to allow the connection to succeed, details can be found here http://twitter4j.org/en/configuration.html#HTTP%20proxy%20server
As an aside, you may want to remove you access token and secret from your post, if they're still valid then someone could login to your account with them.